⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pkg_depends.c

📁 this is the pkg installer for linux
💻 C
📖 第 1 页 / 共 3 页
字号:
/* pkg_depends.c - the itsy package management system   Steven M. Ayer      Copyright (C) 2002 Compaq Computer Corporation   This program is free software; you can redistribute it and/or   modify it under the terms of the GNU General Public License as   published by the Free Software Foundation; either version 2, or (at   your option) any later version.   This program is distributed in the hope that it will be useful, but   WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU   General Public License for more details.*/#include "ipkg.h"#include <errno.h>#include <ctype.h>   #include "pkg.h"#include "ipkg_utils.h"#include "pkg_hash.h"#include "ipkg_message.h"#include "pkg_parse.h"#include "hash_table.h"static int parseDepends(compound_depend_t *compound_depend, hash_table_t * hash, char * depend_str);static depend_t * depend_init(void);static void depend_deinit(depend_t *d);static char ** add_unresolved_dep(pkg_t * pkg, char ** the_lost, int ref_ndx);static char ** merge_unresolved(char ** oldstuff, char ** newstuff);static int is_pkg_in_pkg_vec(pkg_vec_t * vec, pkg_t * pkg);static int pkg_installed_and_constraint_satisfied(pkg_t *pkg, void *cdata){     depend_t *depend = (depend_t *)cdata;     if ((pkg->state_status == SS_INSTALLED || pkg->state_status == SS_UNPACKED) && version_constraints_satisfied(depend, pkg))	  return 1;     else	  return 0;}static int pkg_constraint_satisfied(pkg_t *pkg, void *cdata){     depend_t *depend = (depend_t *)cdata;#if 0     pkg_t * temp = pkg_new();     int comparison;     parseVersion(temp, depend->version);     comparison = pkg_compare_versions(pkg, temp);     free(temp);     fprintf(stderr, "%s: pkg=%s pkg->version=%s constraint=%p type=%d version=%s comparison=%d satisfied=%d\n", 	     __FUNCTION__, pkg->name, pkg->version, 	     depend, depend->constraint, depend->version,	     comparison, version_constraints_satisfied(depend, pkg));#endif     if (version_constraints_satisfied(depend, pkg))	  return 1;     else	  return 0;}/* returns ndependences or negative error value */ int pkg_hash_fetch_unsatisfied_dependencies(ipkg_conf_t *conf, pkg_t * pkg, 					    pkg_vec_t *unsatisfied, char *** unresolved){     pkg_t * satisfier_entry_pkg;     register int i, j, k;     int count, found;     char ** the_lost;     abstract_pkg_t * ab_pkg;     /*       * this is a setup to check for redundant/cyclic dependency checks,       * which are marked at the abstract_pkg level      */     if (!(ab_pkg = pkg->parent)) {	  fprintf(stderr, "%s:%d: something terribly wrong with pkg %s\n", __FUNCTION__, __LINE__, pkg->name);	  *unresolved = NULL;	  return 0;     }     if (ab_pkg->dependencies_checked) {    /* avoid duplicate or cyclic checks */	  *unresolved = NULL;	  return 0;     } else { 	  ab_pkg->dependencies_checked = 1;  /* mark it for subsequent visits */     }     /**/     count = pkg->pre_depends_count + pkg->depends_count + pkg->recommends_count + pkg->suggests_count;     if (!count){	  *unresolved = NULL;	  return 0;     }     the_lost = NULL;	     /* foreach dependency */     for (i = 0; i < count; i++) {	  compound_depend_t * compound_depend = &pkg->depends[i];	  depend_t ** possible_satisfiers = compound_depend->possibilities;;	  found = 0;	  satisfier_entry_pkg = NULL;	  if (compound_depend->type == GREEDY_DEPEND) {	       /* foreach possible satisfier */	       for (j = 0; j < compound_depend->possibility_count; j++) {		    /* foreach provided_by, which includes the abstract_pkg itself */		    abstract_pkg_t *abpkg = possible_satisfiers[j]->pkg;		    abstract_pkg_vec_t *ab_provider_vec = abpkg->provided_by;		    int nposs = ab_provider_vec->len;		    abstract_pkg_t **ab_providers = ab_provider_vec->pkgs; 		    int l;		    for (l = 0; l < nposs; l++) {			 pkg_vec_t *test_vec = ab_providers[l]->pkgs;			 /* if no depends on this one, try the first package that Provides this one */			 if (!test_vec){   /* no pkg_vec hooked up to the abstract_pkg!  (need another feed?) */			      continue;			 }	      			 /* cruise this possiblity's pkg_vec looking for an installed version */			 for (k = 0; k < test_vec->len; k++) {			      pkg_t *pkg_scout = test_vec->pkgs[k];			      /* not installed, and not already known about? */			      if ((pkg_scout->state_want != SW_INSTALL)				  && !pkg_scout->parent->dependencies_checked				  && !is_pkg_in_pkg_vec(unsatisfied, pkg_scout)) {				   char ** newstuff = NULL;				   int rc;				   pkg_vec_t *tmp_vec = pkg_vec_alloc ();				   /* check for not-already-installed dependencies */				   rc = pkg_hash_fetch_unsatisfied_dependencies(conf, 										pkg_scout, 										tmp_vec,										&newstuff);				   if (newstuff == NULL) {					int i;					int ok = 1;					for (i = 0; i < rc; i++) {					    pkg_t *p = tmp_vec->pkgs[i];					    if (p->state_want == SW_INSTALL)						continue;					    ipkg_message(conf, IPKG_DEBUG, "not installing %s due to requirement for %s\n", pkg_scout->name, p->name);					    ok = 0;					    break;					}					pkg_vec_free (tmp_vec);					if (ok) {					    /* mark this one for installation */					    ipkg_message(conf, IPKG_NOTICE, "Adding satisfier for greedy dependence: %s\n", pkg_scout->name);					    pkg_vec_insert(unsatisfied, pkg_scout);					}				   } else  {					ipkg_message(conf, IPKG_DEBUG, "not installing %s due to broken depends \n", pkg_scout->name);					free (newstuff);				   }			      }			 }		    }	       }	       continue;	  }	  /* foreach possible satisfier, look for installed package  */	  for (j = 0; j < compound_depend->possibility_count; j++) {	       /* foreach provided_by, which includes the abstract_pkg itself */	       depend_t *dependence_to_satisfy = possible_satisfiers[j];	       abstract_pkg_t *satisfying_apkg = possible_satisfiers[j]->pkg;	       pkg_t *satisfying_pkg = 		    pkg_hash_fetch_best_installation_candidate(conf, satisfying_apkg, 							       pkg_installed_and_constraint_satisfied, 							       dependence_to_satisfy, 1);               /* Being that I can't test constraing in pkg_hash, I will test it here */	       if (satisfying_pkg != NULL) {                  if (!pkg_installed_and_constraint_satisfied ( satisfying_pkg,dependence_to_satisfy)) {	              satisfying_pkg = NULL;                  }               }	       ipkg_message(conf, IPKG_DEBUG, "%s:%d: satisfying_pkg=%p \n", __FILE__, __LINE__, satisfying_pkg);	       if (satisfying_pkg != NULL) {		    found = 1;		    break;	       }	  }	  /* if nothing installed matches, then look for uninstalled satisfier */	  if (!found) {	       /* foreach possible satisfier, look for installed package  */	       for (j = 0; j < compound_depend->possibility_count; j++) {		    /* foreach provided_by, which includes the abstract_pkg itself */		    depend_t *dependence_to_satisfy = possible_satisfiers[j];		    abstract_pkg_t *satisfying_apkg = possible_satisfiers[j]->pkg;		    pkg_t *satisfying_pkg = 			 pkg_hash_fetch_best_installation_candidate(conf, satisfying_apkg, 								    pkg_constraint_satisfied, 								    dependence_to_satisfy, 1);                    /* Being that I can't test constraing in pkg_hash, I will test it here too */	            if (satisfying_pkg != NULL) {                         if (!pkg_constraint_satisfied ( satisfying_pkg,dependence_to_satisfy)) {                            satisfying_pkg = NULL;                         }                    }		    /* user request overrides package recommendation */		    if (satisfying_pkg != NULL			&& (compound_depend->type == RECOMMEND || compound_depend->type == SUGGEST)			&& (satisfying_pkg->state_want == SW_DEINSTALL || satisfying_pkg->state_want == SW_PURGE)) {			 ipkg_message (conf, IPKG_NOTICE, "%s: ignoring recommendation for %s at user request\n",				       pkg->name, satisfying_pkg->name);			 continue;		    }		    ipkg_message(conf, IPKG_DEBUG, "%s:%d: satisfying_pkg=%p\n", __FILE__, __LINE__, satisfying_pkg);		    if (satisfying_pkg != NULL) {			 satisfier_entry_pkg = satisfying_pkg;			 break;		    }	       }	  }	  /* we didn't find one, add something to the unsatisfied vector */	  if (!found) {	       if (!satisfier_entry_pkg) {		    /* failure to meet recommendations is not an error */		    if (compound_depend->type != RECOMMEND && compound_depend->type != SUGGEST)			 the_lost = add_unresolved_dep(pkg, the_lost, i);		    else			 ipkg_message (conf, IPKG_NOTICE, "%s: unsatisfied recommendation for %s\n",				       pkg->name, compound_depend->possibilities[0]->pkg->name);	       }	       else {		    if (compound_depend->type == SUGGEST) {			 /* just mention it politely */			 ipkg_message (conf, IPKG_NOTICE, "package %s suggests installing %s\n",				       pkg->name, satisfier_entry_pkg->name);		    } else {			 char ** newstuff = NULL;			 			 if (satisfier_entry_pkg != pkg &&			     !is_pkg_in_pkg_vec(unsatisfied, satisfier_entry_pkg)) {			      pkg_vec_insert(unsatisfied, satisfier_entry_pkg);			      pkg_hash_fetch_unsatisfied_dependencies(conf, 								      satisfier_entry_pkg, 								      unsatisfied,								      &newstuff);			      the_lost = merge_unresolved(the_lost, newstuff);			 }		    }	       }	  }     }     *unresolved = the_lost;     return unsatisfied->len;}/*checking for conflicts !in replaces   If a packages conflicts with another but is also replacing it, I should not consider it a   really conflicts   returns 0 if conflicts <> replaces or 1 if conflicts == replaces */int is_pkg_a_replaces(pkg_t *pkg_scout,pkg_t *pkg){    int i ;    int replaces_count = pkg->replaces_count;    abstract_pkg_t **replaces;    if (pkg->replaces_count==0)    // No replaces, it's surely a conflict        return 0;    replaces = pkg->replaces;    for (i = 0; i < replaces_count; i++) {        if (strcmp(pkg_scout->name,pkg->replaces[i]->name)==0) {      // Found            ipkg_message(NULL, IPKG_DEBUG2, "Seems I've found a replace %s %s \n",pkg_scout->name,pkg->replaces[i]->name);            return 1;        }    }    return 0;}/* Abhaya: added support for conflicts */pkg_vec_t * pkg_hash_fetch_conflicts(hash_table_t * hash, pkg_t * pkg){    pkg_vec_t * installed_conflicts, * test_vec;    compound_depend_t * conflicts;    depend_t ** possible_satisfiers;    depend_t * possible_satisfier;    register int i, j, k;    int count;    abstract_pkg_t * ab_pkg;    pkg_t **pkg_scouts;     pkg_t *pkg_scout;     /*      * this is a setup to check for redundant/cyclic dependency checks,      * which are marked at the abstract_pkg level     */    if(!(ab_pkg = pkg->parent)){	fprintf(stderr, "dependency check error.  pkg %s isn't in hash table\n", pkg->name);	return (pkg_vec_t *)NULL;    }    conflicts = pkg->conflicts;    if(!conflicts){	return (pkg_vec_t *)NULL;    }    installed_conflicts = pkg_vec_alloc();    count = pkg->conflicts_count;    /* foreach conflict */    for(i = 0; i < pkg->conflicts_count; i++){	possible_satisfiers = conflicts->possibilities;	/* foreach possible satisfier */	for(j = 0; j < conflicts->possibility_count; j++){            possible_satisfier = possible_satisfiers[j];            if (!possible_satisfier)                fprintf(stderr, "%s:%d: possible_satisfier is null\n", __FUNCTION__, __LINE__);            if (!possible_satisfier->pkg)                fprintf(stderr, "%s:%d: possible_satisfier->pkg is null\n", __FUNCTION__, __LINE__);	    test_vec = possible_satisfier->pkg->pkgs;	    if (test_vec) {                /* pkg_vec found, it is an actual package conflict		 * cruise this possiblity's pkg_vec looking for an installed version */		pkg_scouts = test_vec->pkgs;		for(k = 0; k < test_vec->len; k++){                    pkg_scout = pkg_scouts[k];                    if (!pkg_scout) {                        fprintf(stderr,  "%s: null pkg scout\n", __FUNCTION__);                        continue;                     }		    if ((pkg_scout->state_status == SS_INSTALLED || pkg_scout->state_want == SW_INSTALL) &&		       version_constraints_satisfied(possible_satisfier, pkg_scout) && !is_pkg_a_replaces(pkg_scout,pkg)){ 	 	        if (!is_pkg_in_pkg_vec(installed_conflicts, pkg_scout)){

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -