Exemple #1
0
void buildDependedUponBy(pkg_t * pkg, abstract_pkg_t * ab_pkg)
{
    compound_depend_t *depends;
    int count;
    int i, j;
    abstract_pkg_t *ab_depend;

    count = pkg->pre_depends_count + pkg->depends_count + pkg->recommends_count
        + pkg->suggests_count;

    for (i = 0; i < count; i++) {
        depends = &pkg->depends[i];
        int wrong_type = depends->type != PREDEPEND
                && depends->type != DEPEND
                && depends->type != RECOMMEND;
        if (wrong_type)
            continue;
        for (j = 0; j < depends->possibility_count; j++) {
            ab_depend = depends->possibilities[j]->pkg;
            if (!abstract_pkg_vec_contains(ab_depend->depended_upon_by, ab_pkg))
                abstract_pkg_vec_insert(ab_depend->depended_upon_by, ab_pkg);
        }
    }
}
Exemple #2
0
pkg_t *pkg_hash_fetch_best_installation_candidate(ipkg_conf_t *conf, abstract_pkg_t *apkg, 
						  int (*constraint_fcn)(pkg_t *pkg, void *cdata), void *cdata, int quiet)
{
     int i; 
     int nprovides = 0;
     int nmatching = 0;
     pkg_vec_t *matching_pkgs = pkg_vec_alloc();
     abstract_pkg_vec_t *matching_apkgs = abstract_pkg_vec_alloc();
     abstract_pkg_vec_t *provided_apkg_vec;
     abstract_pkg_t **provided_apkgs;
     abstract_pkg_vec_t *providers = abstract_pkg_vec_alloc();
     pkg_t *latest_installed_parent = NULL;
     pkg_t *latest_matching = NULL;
     pkg_t *held_pkg = NULL;
     pkg_t *good_pkg_by_name = NULL;

     if (matching_apkgs == NULL || providers == NULL || 
         apkg == NULL || apkg->provided_by == NULL || (apkg->provided_by->len == 0))
	  return NULL;

     ipkg_message(conf, IPKG_DEBUG, "best installation candidate for %s\n", apkg->name);

     provided_apkg_vec = apkg->provided_by;
     nprovides = provided_apkg_vec->len;
     provided_apkgs = provided_apkg_vec->pkgs;
     if (nprovides > 1)
	  ipkg_message(conf, IPKG_DEBUG, " apkg=%s nprovides=%d\n", apkg->name, nprovides);

     /* accumulate all the providers */
     for (i = 0; i < nprovides; i++) {
	  abstract_pkg_t *provider_apkg = provided_apkgs[i];
	  ipkg_message(conf, IPKG_DEBUG, " adding %s to providers\n", provider_apkg->name);
	  abstract_pkg_vec_insert(providers, provider_apkg);
     }
     nprovides = providers->len;

     for (i = 0; i < nprovides; i++) {
	  abstract_pkg_t *provider_apkg = abstract_pkg_vec_get(providers, i);
	  abstract_pkg_t *replacement_apkg = NULL;
	  pkg_vec_t *vec;

	  if (provider_apkg->replaced_by && provider_apkg->replaced_by->len) {
	       replacement_apkg = provider_apkg->replaced_by->pkgs[0];
	       if (provider_apkg->replaced_by->len > 1) {
		    ipkg_message(conf, IPKG_NOTICE, "Multiple replacers for %s, using first one (%s)\n", 
				 provider_apkg->name, replacement_apkg->name);
	       }
	  }

	  if (replacement_apkg)
	       ipkg_message(conf, IPKG_DEBUG, "   replacement_apkg=%s for provider_apkg=%s\n", 
			    replacement_apkg->name, provider_apkg->name);

	  if (replacement_apkg && (replacement_apkg != provider_apkg)) {
	       if (abstract_pkg_vec_contains(providers, replacement_apkg))
		    continue;
	       else
		    provider_apkg = replacement_apkg;
	  }

	  if (!(vec = provider_apkg->pkgs)) {
	       ipkg_message(conf, IPKG_DEBUG, "   no pkgs for provider_apkg %s\n", provider_apkg->name);
	       continue;
	  }
    

	  /* now check for supported architecture */
	  {
	       int max_count = 0;
	       int i;

	       /* count packages matching max arch priority and keep track of last one */
	       for (i = 0; i < vec->len; i++) {
		    pkg_t *maybe = vec->pkgs[i];
		    ipkg_message(conf, IPKG_DEBUG, "  %s arch=%s arch_priority=%d version=%s  \n",
				 maybe->name, maybe->architecture, maybe->arch_priority, maybe->version);
		    if (maybe->arch_priority > 0)  {
			 max_count++;
			 abstract_pkg_vec_insert(matching_apkgs, maybe->parent);
			 pkg_vec_insert(matching_pkgs, maybe);
		    }
	       }
	  }
     }

     if (matching_pkgs->len > 1)
	  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);

/* Here it is usefull, if ( matching_apkgs->len > 1 ), to test if one of this matching packages has the same name of the
   needed package. In this case, I would return it for install, otherwise I will continue with the procedure */
/* The problem is what to do when there are more than a mathing package, with the same name and several version ?
   Until now I always got the latest, but that breaks the downgrade option.
   If I stop at the first one, I would probably miss the new ones 
   Maybe the way is to have some kind of flag somewhere, to see if the package been asked to install is from a file,
   or from a Packages feed.
   It it is from a file it always need to be checked whatever version I have in feeds or everywhere, according to force-down or whatever options*/
/*Pigi*/

     for (i = 0; i < matching_pkgs->len; i++) {
	  pkg_t *matching = matching_pkgs->pkgs[i];
          if (constraint_fcn(matching, cdata)) {  /* We found it */
             ipkg_message(conf, IPKG_DEBUG, " Found a valid candidate for the install: %s %s  \n", matching->name, matching->version) ;
             good_pkg_by_name = matching;
             if ( matching->provided_by_hand == 1 )    /* It has been provided by hand, so it is what user want */
                break;                                 
          }
     }


     for (i = 0; i < matching_pkgs->len; i++) {
	  pkg_t *matching = matching_pkgs->pkgs[i];
	  latest_matching = matching;
	  if (matching->parent->state_status == SS_INSTALLED || matching->parent->state_status == SS_UNPACKED)
	       latest_installed_parent = matching;
	  if (matching->state_flag & (SF_HOLD|SF_PREFER)) {
	       if (held_pkg)
		    ipkg_message(conf, IPKG_ERROR, "Multiple packages (%s and %s) providing same name marked HOLD or PREFER.  Using latest.\n",
				 held_pkg->name, matching->name);
	       held_pkg = matching;
	  }
     }

     if (!good_pkg_by_name && !held_pkg && !latest_installed_parent && matching_apkgs->len > 1 && !quiet) {
	  ipkg_message(conf, IPKG_ERROR, "Package=%s, %d matching providers\n",
		       apkg->name, matching_apkgs->len);
	  for (i = 0; i < matching_apkgs->len; i++) {
              abstract_pkg_t *matching = matching_apkgs->pkgs[i];
              ipkg_message(conf, IPKG_ERROR, "    %s\n", matching->name);
	  }
	  ipkg_message(conf, IPKG_ERROR, "Please select one with ipkg install or ipkg flag prefer\n");
     }

     if (matching_apkgs->len > 1 && conf->verbosity > 1) {
	  ipkg_message(conf, IPKG_NOTICE, "%s: for apkg=%s, %d matching pkgs\n",
		       __FUNCTION__, apkg->name, matching_pkgs->len);
	  for (i = 0; i < matching_pkgs->len; i++) {
	       pkg_t *matching = matching_pkgs->pkgs[i];
	       ipkg_message(conf, IPKG_INFO, "    %s %s %s\n",
			    matching->name, matching->version, matching->architecture);
	  }
     }

     nmatching = matching_apkgs->len;

     pkg_vec_free(matching_pkgs);
     abstract_pkg_vec_free(matching_apkgs);
     abstract_pkg_vec_free(providers);

     if (good_pkg_by_name) {   /* We found a good candidate, we will install it */ 
	  return good_pkg_by_name;
     }
     if (held_pkg) {
	  ipkg_message(conf, IPKG_INFO, "  using held package %s\n", held_pkg->name);
	  return held_pkg;
     }
     if (latest_installed_parent) {
	  ipkg_message(conf, IPKG_INFO, "  using latest version of installed package %s\n", latest_installed_parent->name);
	  return latest_installed_parent;
     }
     if (nmatching > 1) {
	  ipkg_message(conf, IPKG_INFO, "  no matching pkg out of matching_apkgs=%d\n", nmatching);
	  return NULL;
     }
     if (latest_matching) {
	  ipkg_message(conf, IPKG_INFO, "  using latest matching %s %s %s\n",
		       latest_matching->name, latest_matching->version, latest_matching->architecture);
	  return latest_matching;
     }
     return NULL;
}