示例#1
0
文件: expac.c 项目: aissat/expac
static alpm_list_t *search_groups(alpm_list_t *dbs, alpm_list_t *groupnames)
{
  alpm_list_t *i, *j, *packages = NULL;

  for(i = groupnames; i; i = i->next) {
    for(j = dbs; j; j = j->next) {
      alpm_group_t *grp = alpm_db_get_group(j->data, i->data);
      if(grp != NULL) {
        packages = alpm_list_join(packages, alpm_list_copy(grp->packages));
      }
    }
  }

  return packages;
}
示例#2
0
int _alpm_sync_prepare(alpm_handle_t *handle, alpm_list_t **data)
{
	alpm_list_t *i, *j;
	alpm_list_t *deps = NULL;
	alpm_list_t *unresolvable = NULL;
	int from_sync = 0;
	int ret = 0;
	alpm_trans_t *trans = handle->trans;
	alpm_event_t event;

	if(data) {
		*data = NULL;
	}

	for(i = trans->add; i; i = i->next) {
		alpm_pkg_t *spkg = i->data;
		if (spkg->origin == ALPM_PKG_FROM_SYNCDB){
			from_sync = 1;
			break;
		}
	}

	/* ensure all sync database are valid if we will be using them */
	for(i = handle->dbs_sync; i; i = i->next) {
		const alpm_db_t *db = i->data;
		if(db->status & DB_STATUS_INVALID) {
			RET_ERR(handle, ALPM_ERR_DB_INVALID, -1);
		}
		/* missing databases are not allowed if we have sync targets */
		if(from_sync && db->status & DB_STATUS_MISSING) {
			RET_ERR(handle, ALPM_ERR_DB_NOT_FOUND, -1);
		}
	}

	if(!(trans->flags & ALPM_TRANS_FLAG_NODEPS)) {
		alpm_list_t *resolved = NULL;
		alpm_list_t *remove = alpm_list_copy(trans->remove);
		alpm_list_t *localpkgs;

		/* Build up list by repeatedly resolving each transaction package */
		/* Resolve targets dependencies */
		event.type = ALPM_EVENT_RESOLVEDEPS_START;
		EVENT(handle, &event);
		_alpm_log(handle, ALPM_LOG_DEBUG, "resolving target's dependencies\n");

		/* build remove list for resolvedeps */
		for(i = trans->add; i; i = i->next) {
			alpm_pkg_t *spkg = i->data;
			for(j = spkg->removes; j; j = j->next) {
				remove = alpm_list_add(remove, j->data);
			}
		}

		/* Compute the fake local database for resolvedeps (partial fix for the
		 * phonon/qt issue) */
		localpkgs = alpm_list_diff(_alpm_db_get_pkgcache(handle->db_local),
				trans->add, _alpm_pkg_cmp);

		/* Resolve packages in the transaction one at a time, in addition
		   building up a list of packages which could not be resolved. */
		for(i = trans->add; i; i = i->next) {
			alpm_pkg_t *pkg = i->data;
			if(_alpm_resolvedeps(handle, localpkgs, pkg, trans->add,
						&resolved, remove, data) == -1) {
				unresolvable = alpm_list_add(unresolvable, pkg);
			}
			/* Else, [resolved] now additionally contains [pkg] and all of its
			   dependencies not already on the list */
		}
		alpm_list_free(localpkgs);
		alpm_list_free(remove);

		/* If there were unresolvable top-level packages, prompt the user to
		   see if they'd like to ignore them rather than failing the sync */
		if(unresolvable != NULL) {
			alpm_question_remove_pkgs_t question = {
				.type = ALPM_QUESTION_REMOVE_PKGS,
				.skip = 0,
				.packages = unresolvable
			};
			QUESTION(handle, &question);
			if(question.skip) {
				/* User wants to remove the unresolvable packages from the
				   transaction. The packages will be removed from the actual
				   transaction when the transaction packages are replaced with a
				   dependency-reordered list below */
				handle->pm_errno = 0;
				if(data) {
					alpm_list_free_inner(*data,
							(alpm_list_fn_free)alpm_depmissing_free);
					alpm_list_free(*data);
					*data = NULL;
				}
			} else {
				/* pm_errno was set by resolvedeps, callback may have overwrote it */
				handle->pm_errno = ALPM_ERR_UNSATISFIED_DEPS;
				alpm_list_free(resolved);
				alpm_list_free(unresolvable);
				ret = -1;
				goto cleanup;
			}
		}

		/* Set DEPEND reason for pulled packages */
		for(i = resolved; i; i = i->next) {
			alpm_pkg_t *pkg = i->data;
			if(!alpm_pkg_find(trans->add, pkg->name)) {
				pkg->reason = ALPM_PKG_REASON_DEPEND;
			}
		}

		/* Unresolvable packages will be removed from the target list; set these
		 * aside in the transaction as a list we won't operate on. If we free them
		 * before the end of the transaction, we may kill pointers the frontend
		 * holds to package objects. */
		trans->unresolvable = unresolvable;

		alpm_list_free(trans->add);
		trans->add = resolved;

		event.type = ALPM_EVENT_RESOLVEDEPS_DONE;
		EVENT(handle, &event);
	}
示例#3
0
static int parse_options(int argc, char *argv[], alpm_handle_t *alpm) {
  int opt, option_index = 0;
  const char *i;

  static struct option opts[] = {
    {"readone",   no_argument,        0, '1'},
    {"delim",     required_argument,  0, 'd'},
    {"listdelim", required_argument,  0, 'l'},
    {"group",     required_argument,  0, 'g'},
    {"help",      no_argument,        0, 'h'},
    {"file",      no_argument,        0, 'p'},
    {"humansize", required_argument,  0, 'H'},
    {"query",     no_argument,        0, 'Q'},
    {"sync",      no_argument,        0, 'S'},
    {"search",    no_argument,        0, 's'},
    {"timefmt",   required_argument,  0, 't'},
    {"verbose",   no_argument,        0, 'v'},
    {0, 0, 0, 0}
  };

  while (-1 != (opt = getopt_long(argc, argv, "1l:d:gH:hf:pQSst:v", opts, &option_index))) {
    switch (opt) {
      case 'S':
        if (dblist) {
          fprintf(stderr, "error: can only select one repo option (use -h for help)\n");
          return 1;
        }
        dblist = alpm_list_copy(alpm_get_syncdbs(alpm));
        break;
      case 'Q':
        if (dblist) {
          fprintf(stderr, "error: can only select one repo option (use -h for help)\n");
          return 1;
        }
        dblist = alpm_list_add(dblist, db_local);
        opt_local = true;
        break;
      case '1':
        opt_readone = true;
        break;
      case 'd':
        opt_delim = optarg;
        break;
      case 'g':
        opt_groups = true;
        break;
      case 'l':
        opt_listdelim = optarg;
        break;
      case 'H':
        for(i = SIZE_TOKENS; *i; i++) {
          if(*i == *optarg) {
            opt_humansize = *optarg;
            break;
          }
        }
        if(*i == '\0') {
          fprintf(stderr, "error: invalid SI size formatter: %c\n", *optarg);
          return 1;
        }
        break;
      case 'h':
        usage();
        return 1;
      case 'p':
        opt_localpkg = true;
        break;
      case 's':
        opt_search = true;
        break;
      case 't':
        opt_timefmt = optarg;
        break;
      case 'v':
        opt_verbose = true;
        break;

      case '?':
        return 1;
      default:
        return 1;
    }
  }

  if (optind < argc) {
    opt_format = argv[optind++];
  } else {
    fprintf(stderr, "error: missing format string (use -h for help)\n");
    return 1;
  }

  while (optind < argc) {
    targets = alpm_list_add(targets, argv[optind++]);
  }

  return 0;
}
示例#4
0
文件: deps.c 项目: mineo/pacman
/**
 * Computes resolvable dependencies for a given package and adds that package
 * and those resolvable dependencies to a list.
 *
 * @param handle the context handle
 * @param localpkgs is the list of local packages
 * @param pkg is the package to resolve
 * @param packages is a pointer to a list of packages which will be
 *        searched first for any dependency packages needed to complete the
 *        resolve, and to which will be added any [pkg] and all of its
 *        dependencies not already on the list
 * @param remove is the set of packages which will be removed in this
 *        transaction
 * @param data returns the dependency which could not be satisfied in the
 *        event of an error
 * @return 0 on success, with [pkg] and all of its dependencies not already on
 *         the [*packages] list added to that list, or -1 on failure due to an
 *         unresolvable dependency, in which case the [*packages] list will be
 *         unmodified by this function
 */
int _alpm_resolvedeps(pmhandle_t *handle, alpm_list_t *localpkgs, pmpkg_t *pkg,
                      alpm_list_t *preferred, alpm_list_t **packages,
                      alpm_list_t *remove, alpm_list_t **data)
{
	int ret = 0;
	alpm_list_t *i, *j;
	alpm_list_t *targ;
	alpm_list_t *deps = NULL;
	alpm_list_t *packages_copy;

	if(_alpm_pkg_find(*packages, pkg->name) != NULL) {
		return 0;
	}

	/* Create a copy of the packages list, so that it can be restored
	   on error */
	packages_copy = alpm_list_copy(*packages);
	/* [pkg] has not already been resolved into the packages list, so put it
	   on that list */
	*packages = alpm_list_add(*packages, pkg);

	_alpm_log(handle, PM_LOG_DEBUG, "started resolving dependencies\n");
	for(i = alpm_list_last(*packages); i; i = i->next) {
		pmpkg_t *tpkg = i->data;
		targ = alpm_list_add(NULL, tpkg);
		deps = alpm_checkdeps(handle, localpkgs, remove, targ, 0);
		alpm_list_free(targ);

		for(j = deps; j; j = j->next) {
			pmdepmissing_t *miss = j->data;
			pmdepend_t *missdep = miss->depend;
			/* check if one of the packages in the [*packages] list already satisfies
			 * this dependency */
			if(find_dep_satisfier(*packages, missdep)) {
				_alpm_depmiss_free(miss);
				continue;
			}
			/* check if one of the packages in the [preferred] list already satisfies
			 * this dependency */
			pmpkg_t *spkg = find_dep_satisfier(preferred, missdep);
			if(!spkg) {
				/* find a satisfier package in the given repositories */
				spkg = resolvedep(handle, missdep, handle->dbs_sync, *packages, 0);
			}
			if(!spkg) {
				handle->pm_errno = PM_ERR_UNSATISFIED_DEPS;
				char *missdepstring = alpm_dep_compute_string(missdep);
				_alpm_log(handle, PM_LOG_WARNING,
						_("cannot resolve \"%s\", a dependency of \"%s\"\n"),
						missdepstring, tpkg->name);
				free(missdepstring);
				if(data) {
					*data = alpm_list_add(*data, miss);
				}
				ret = -1;
			} else {
				_alpm_log(handle, PM_LOG_DEBUG, "pulling dependency %s (needed by %s)\n",
						alpm_pkg_get_name(spkg), alpm_pkg_get_name(tpkg));
				*packages = alpm_list_add(*packages, spkg);
				_alpm_depmiss_free(miss);
			}
		}
		alpm_list_free(deps);
	}

	if(ret != 0) {
		alpm_list_free(*packages);
		*packages = packages_copy;
	} else {
		alpm_list_free(packages_copy);
	}
	_alpm_log(handle, PM_LOG_DEBUG, "finished resolving dependencies\n");
	return ret;
}
示例#5
0
文件: deps.c 项目: mineo/pacman
/** Checks dependencies and returns missing ones in a list.
 * Dependencies can include versions with depmod operators.
 * @param handle the context handle
 * @param pkglist the list of local packages
 * @param remove an alpm_list_t* of packages to be removed
 * @param upgrade an alpm_list_t* of packages to be upgraded (remove-then-upgrade)
 * @param reversedeps handles the backward dependencies
 * @return an alpm_list_t* of pmdepmissing_t pointers.
 */
alpm_list_t SYMEXPORT *alpm_checkdeps(pmhandle_t *handle, alpm_list_t *pkglist,
		alpm_list_t *remove, alpm_list_t *upgrade, int reversedeps)
{
	alpm_list_t *i, *j;
	alpm_list_t *targets, *dblist = NULL, *modified = NULL;
	alpm_list_t *baddeps = NULL;
	int nodepversion;

	CHECK_HANDLE(handle, return NULL);

	targets = alpm_list_join(alpm_list_copy(remove), alpm_list_copy(upgrade));
	for(i = pkglist; i; i = i->next) {
		pmpkg_t *pkg = i->data;
		if(_alpm_pkg_find(targets, pkg->name)) {
			modified = alpm_list_add(modified, pkg);
		} else {
			dblist = alpm_list_add(dblist, pkg);
		}
	}
	alpm_list_free(targets);

	nodepversion = no_dep_version(handle);

	/* look for unsatisfied dependencies of the upgrade list */
	for(i = upgrade; i; i = i->next) {
		pmpkg_t *tp = i->data;
		_alpm_log(handle, PM_LOG_DEBUG, "checkdeps: package %s-%s\n",
				alpm_pkg_get_name(tp), alpm_pkg_get_version(tp));

		for(j = alpm_pkg_get_depends(tp); j; j = j->next) {
			pmdepend_t *depend = j->data;
			depend = filtered_depend(depend, nodepversion);
			/* 1. we check the upgrade list */
			/* 2. we check database for untouched satisfying packages */
			if(!find_dep_satisfier(upgrade, depend) &&
			   !find_dep_satisfier(dblist, depend)) {
				/* Unsatisfied dependency in the upgrade list */
				pmdepmissing_t *miss;
				char *missdepstring = alpm_dep_compute_string(depend);
				_alpm_log(handle, PM_LOG_DEBUG, "checkdeps: missing dependency '%s' for package '%s'\n",
						missdepstring, alpm_pkg_get_name(tp));
				free(missdepstring);
				miss = depmiss_new(alpm_pkg_get_name(tp), depend, NULL);
				baddeps = alpm_list_add(baddeps, miss);
			}
			release_filtered_depend(depend, nodepversion);
		}
	}

	if(reversedeps) {
		/* reversedeps handles the backwards dependencies, ie,
		 * the packages listed in the requiredby field. */
		for(i = dblist; i; i = i->next) {
			pmpkg_t *lp = i->data;
			for(j = alpm_pkg_get_depends(lp); j; j = j->next) {
				pmdepend_t *depend = j->data;
				depend = filtered_depend(depend, nodepversion);
				pmpkg_t *causingpkg = find_dep_satisfier(modified, depend);
				/* we won't break this depend, if it is already broken, we ignore it */
				/* 1. check upgrade list for satisfiers */
				/* 2. check dblist for satisfiers */
				if(causingpkg &&
				   !find_dep_satisfier(upgrade, depend) &&
				   !find_dep_satisfier(dblist, depend)) {
					pmdepmissing_t *miss;
					char *missdepstring = alpm_dep_compute_string(depend);
					_alpm_log(handle, PM_LOG_DEBUG, "checkdeps: transaction would break '%s' dependency of '%s'\n",
							missdepstring, alpm_pkg_get_name(lp));
					free(missdepstring);
					miss = depmiss_new(lp->name, depend, alpm_pkg_get_name(causingpkg));
					baddeps = alpm_list_add(baddeps, miss);
				}
				release_filtered_depend(depend, nodepversion);
			}
		}
	}

	alpm_list_free(modified);
	alpm_list_free(dblist);

	return baddeps;
}
示例#6
0
/**
 * pacman_list_copy:
 * @list: A #PacmanList.
 *
 * Creates a new list with the same contents as @list.
 *
 * Returns: A #PacmanList. Free with pacman_list_free().
 */
PacmanList *pacman_list_copy (const PacmanList *list) {
	return alpm_list_copy (list);
}
示例#7
0
int main(int argc, char **argv)
{
	alpm_list_t *i;
	int ret = 0;

	if(!(config = parse_opts(argc, argv))) {
		ret = 1;
		goto cleanup;
	}

	if(checks == 0) {
		checks = CHECK_DEPENDS | CHECK_FILES;
	}

	if(!(handle = pu_initialize_handle_from_config(config))) {
		fprintf(stderr, "error: failed to initialize alpm.\n");
		ret = 1;
		goto cleanup;
	}

	localdb = alpm_get_localdb(handle);
	pkgcache = alpm_db_get_pkgcache(localdb);

	for(; optind < argc; ++optind) {
		if(load_pkg(argv[optind]) == NULL) { ret = 1; }
	}
	if(!isatty(fileno(stdin)) && errno != EBADF) {
		char *buf = NULL;
		size_t len = 0;
		ssize_t read;

		while((read = getdelim(&buf, &len, isep, stdin)) != -1) {
			if(buf[read - 1] == isep) { buf[read - 1] = '\0'; }
			if(load_pkg(buf) == NULL) { ret = 1; }
		}
		free(buf);
	}

	if(ret) { goto cleanup; }

	if(packages == NULL) {
		packages = alpm_list_copy(pkgcache);
		recursive = 0;
	} else if(recursive) {
		/* load [opt-]depends */
		alpm_list_t *i, *originals = alpm_list_copy(packages);
		for(i = originals; i; i = alpm_list_next(i)) {
			add_deps(i->data);
		}
		alpm_list_free(originals);
	}

	for(i = packages; i; i = alpm_list_next(i)) {
		int pkgerr = 0;
#define RUNCHECK(t, b) if((checks & t) && b != 0) { pkgerr = ret = 1; }
		RUNCHECK(CHECK_DEPENDS, check_depends(i->data));
		RUNCHECK(CHECK_OPT_DEPENDS, check_opt_depends(i->data));
		RUNCHECK(CHECK_FILES, check_files(i->data));
		RUNCHECK(CHECK_FILE_PROPERTIES, check_file_properties(i->data));
		RUNCHECK(CHECK_MD5SUM, check_md5sum(i->data));
		RUNCHECK(CHECK_SHA256SUM, check_sha256sum(i->data));
#undef RUNCHECK
		if(pkgerr && list_broken) { printf("%s\n", alpm_pkg_get_name(i->data)); }
	}

cleanup:
	alpm_list_free(packages);
	alpm_release(handle);
	pu_config_free(config);

	return ret;
}