opkg: Convert "multiple packages" message to NOTICE rather than ERROR
[oweals/opkg-lede.git] / libopkg / pkg_hash.c
index b293195cb1747d111796d7263afbfa139f3c0e4a..97613e5c6ea5275ab4eed4a430647ae0d8789024 100644 (file)
@@ -53,8 +53,36 @@ int pkg_hash_init(const char *name, hash_table_t *hash, int len)
   return hash_table_init(name, hash, len);
 }
 
+void free_pkgs (const char *key, void *entry, void *data)
+{
+  int i;
+  abstract_pkg_t *ab_pkg;
+
+  /* each entry in the hash table is an abstract package, which contains a list
+   * of packages that provide the abstract package */
+  
+  ab_pkg = (abstract_pkg_t*) entry;
+
+  if (ab_pkg->pkgs)
+  {
+    for (i = 0; i < ab_pkg->pkgs->len; i++)
+    {
+      pkg_deinit (ab_pkg->pkgs->pkgs[i]);
+      free (ab_pkg->pkgs->pkgs[i]);
+    }
+  }
+
+  abstract_pkg_vec_free (ab_pkg->provided_by);
+  abstract_pkg_vec_free (ab_pkg->replaced_by);
+  pkg_vec_free (ab_pkg->pkgs);
+  free (ab_pkg->depended_upon_by);
+  free (ab_pkg->name);
+  free (ab_pkg);
+}
+
 void pkg_hash_deinit(hash_table_t *hash)
 {
+  hash_table_foreach (hash, free_pkgs, NULL);
   hash_table_deinit(hash);
 }
 
@@ -112,6 +140,7 @@ int pkg_hash_add_from_file(opkg_conf_t *conf, const char *file_name,
               }
               hash_insert_pkg(hash, pkg, is_status_file,conf);
          } else {
+              pkg_deinit (pkg);
               free(pkg);
          }
      }
@@ -141,7 +170,7 @@ abstract_pkg_vec_t *pkg_hash_fetch_all_installation_candidates(hash_table_t *has
 
 
 pkg_t *pkg_hash_fetch_best_installation_candidate(opkg_conf_t *conf, abstract_pkg_t *apkg, 
-                                                 int (*constraint_fcn)(pkg_t *pkg, void *cdata), void *cdata, int quiet)
+                                                 int (*constraint_fcn)(pkg_t *pkg, void *cdata), void *cdata, int quiet, int *err)
 {
      int i; 
      int nprovides = 0;
@@ -156,6 +185,9 @@ pkg_t *pkg_hash_fetch_best_installation_candidate(opkg_conf_t *conf, abstract_pk
      pkg_t *held_pkg = NULL;
      pkg_t *good_pkg_by_name = NULL;
 
+     if (err)
+       *err = 0;
+
      if (matching_apkgs == NULL || providers == NULL || 
          apkg == NULL || apkg->provided_by == NULL || (apkg->provided_by->len == 0))
          return NULL;
@@ -222,6 +254,13 @@ pkg_t *pkg_hash_fetch_best_installation_candidate(opkg_conf_t *conf, abstract_pk
                         pkg_vec_insert(matching_pkgs, maybe);
                    }
               }
+
+               if (vec->len > 0 && matching_pkgs->len < 1)
+               {
+                 opkg_message (conf, OPKG_ERROR, "Packages were found, but none compatible with the architectures configured\n");
+                 if (err)
+                   *err = OPKG_PKG_HAS_NO_AVAILABLE_ARCH;
+               }
          }
      }
 
@@ -258,7 +297,7 @@ pkg_t *pkg_hash_fetch_best_installation_candidate(opkg_conf_t *conf, abstract_pk
               latest_installed_parent = matching;
          if (matching->state_flag & (SF_HOLD|SF_PREFER)) {
               if (held_pkg)
-                   opkg_message(conf, OPKG_ERROR, "Multiple packages (%s and %s) providing same name marked HOLD or PREFER.  Using latest.\n",
+                   opkg_message(conf, OPKG_NOTICE, "Multiple packages (%s and %s) providing same name marked HOLD or PREFER.  Using latest.\n",
                                 held_pkg->name, matching->name);
               held_pkg = matching;
          }
@@ -322,15 +361,18 @@ static int pkg_name_constraint_fcn(pkg_t *pkg, void *cdata)
          return 0;   
 }
 
-pkg_t *pkg_hash_fetch_best_installation_candidate_by_name(opkg_conf_t *conf, const char *name)
+pkg_t *pkg_hash_fetch_best_installation_candidate_by_name(opkg_conf_t *conf, const char *name, int *err)
 {
      hash_table_t *hash = &conf->pkg_hash;
      abstract_pkg_t *apkg = NULL;
+     pkg_t *ret;
 
      if (!(apkg = abstract_pkg_fetch_by_name(hash, name)))
          return NULL;
-     
-     return pkg_hash_fetch_best_installation_candidate(conf, apkg, pkg_name_constraint_fcn, apkg->name, 0);
+
+     ret = pkg_hash_fetch_best_installation_candidate(conf, apkg, pkg_name_constraint_fcn, apkg->name, 0, err);
+
+     return ret;
 }
 
 
@@ -488,7 +530,7 @@ static void pkg_hash_dump_helper(const char *pkg_name, void *entry, void *data)
   if (dependents != NULL)
     while (dependents [i] != NULL && i < ab_pkg->provided_by->len)
       printf ("\tprovided by - %s\n", dependents [i ++]->name);
-  pkg = pkg_hash_fetch_best_installation_candidate_by_name (conf, ab_pkg->name);
+  pkg = pkg_hash_fetch_best_installation_candidate_by_name (conf, ab_pkg->name, NULL);
   if (pkg) {
     i = 0;
     while (i < pkg->depends_count)