libopkg: implement pkg_hash_load_package_details() helper
[oweals/opkg-lede.git] / libopkg / pkg_hash.c
index 821cc71886e735e7f70a0446b73e4e8f8416e848..3b49301ec488f028e682af95c2beebbfb45db546 100644 (file)
@@ -79,7 +79,7 @@ int dist_hash_add_from_file(const char *lists_dir, pkg_src_t * dist)
                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)) {
+                       if (pkg_hash_add_from_file(list_file, dist, NULL, 0, 0)) {
                                free(list_file);
                                return -1;
                        }
@@ -95,7 +95,7 @@ int dist_hash_add_from_file(const char *lists_dir, pkg_src_t * dist)
 
 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)
 {
        pkg_t *pkg;
        FILE *fp;
@@ -121,6 +121,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);
@@ -166,7 +167,7 @@ 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)
 {
        pkg_src_list_elt_t *iter;
        pkg_src_t *src, *subdist;
@@ -185,7 +186,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)) {
                                free(list_file);
                                return -1;
                        }
@@ -213,7 +214,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))
                                return -1;
                }
        }
@@ -221,6 +222,46 @@ int pkg_hash_load_status_files(void)
        return 0;
 }
 
+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);
+
+               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;
+}
+
 pkg_t *pkg_hash_fetch_best_installation_candidate(abstract_pkg_t * apkg,
                                                  int (*constraint_fcn) (pkg_t *
                                                                         pkg,