예제 #1
0
static alpm_pkghash_t *pkghash_add_pkg(alpm_pkghash_t *hash, alpm_pkg_t *pkg,
		int sorted)
{
	alpm_list_t *ptr;
	unsigned int position;

	if(pkg == NULL || hash == NULL) {
		return hash;
	}

	if(hash->entries >= hash->limit) {
		hash = rehash(hash);
	}

	position = get_hash_position(pkg->name_hash, hash);

	ptr = malloc(sizeof(alpm_list_t));
	if(ptr == NULL) {
		return hash;
	}

	ptr->data = pkg;
	ptr->prev = ptr;
	ptr->next = NULL;

	hash->hash_table[position] = ptr;
	if(!sorted) {
		hash->list = alpm_list_join(hash->list, ptr);
	} else {
		hash->list = alpm_list_mmerge(hash->list, ptr, _alpm_pkg_cmp);
	}

	hash->entries += 1;
	return hash;
}
예제 #2
0
파일: expac.c 프로젝트: Acidburn0zzz/expac
static alpm_list_t *search_packages(alpm_list_t *dbs, alpm_list_t *targets) {
  alpm_list_t *i, *packages = NULL;

  for (i = dbs; i; i = i->next) {
    packages = alpm_list_join(packages, alpm_db_search(i->data, targets));
  }

  return packages;
}
예제 #3
0
파일: expac.c 프로젝트: Acidburn0zzz/expac
static alpm_list_t *all_packages(alpm_list_t *dbs) {
  alpm_list_t *i, *packages = NULL;

  for (i = dbs; i; i = i->next) {
    packages = alpm_list_join(packages, alpm_list_copy(alpm_db_get_pkgcache(i->data)));
  }

  return packages;
}
예제 #4
0
파일: expac.c 프로젝트: Acidburn0zzz/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;
}
예제 #5
0
파일: pacrat.c 프로젝트: vodik/pacrat
alpm_list_t *alpm_all_backups(int everything) /* {{{ */
{
	alpm_list_t *backups = NULL;
	const alpm_list_t *i;

	alpm_db_t *db = alpm_get_localdb(pmhandle);
	alpm_list_t *targets = cfg.targets ? alpm_db_search(db, cfg.targets) : alpm_db_get_pkgcache(db);

	for (i = targets; i; i = i->next) {
		alpm_list_t *pkg_backups = alpm_find_backups(i->data, everything);
		backups = alpm_list_join(backups, pkg_backups);
	}

	return backups;
} /* }}} */
예제 #6
0
파일: sync.c 프로젝트: vadmium/pacman-arch
/** Search for packages to upgrade and add them to the transaction. */
int SYMEXPORT alpm_sync_sysupgrade(alpm_handle_t *handle, int enable_downgrade)
{
	alpm_list_t *i, *j;
	alpm_trans_t *trans;

	CHECK_HANDLE(handle, return -1);
	trans = handle->trans;
	ASSERT(trans != NULL, RET_ERR(handle, ALPM_ERR_TRANS_NULL, -1));
	ASSERT(trans->state == STATE_INITIALIZED, RET_ERR(handle, ALPM_ERR_TRANS_NOT_INITIALIZED, -1));

	_alpm_log(handle, ALPM_LOG_DEBUG, "checking for package upgrades\n");
	for(i = _alpm_db_get_pkgcache(handle->db_local); i; i = i->next) {
		alpm_pkg_t *lpkg = i->data;

		if(alpm_pkg_find(trans->add, lpkg->name)) {
			_alpm_log(handle, ALPM_LOG_DEBUG, "%s is already in the target list -- skipping\n", lpkg->name);
			continue;
		}

		/* Search for literal then replacers in each sync database. */
		for(j = handle->dbs_sync; j; j = j->next) {
			alpm_db_t *sdb = j->data;
			/* Check sdb */
			alpm_pkg_t *spkg = _alpm_db_get_pkgfromcache(sdb, lpkg->name);
			int literal_upgrade = 0;
			if(spkg) {
				literal_upgrade = check_literal(handle, lpkg, spkg, enable_downgrade);
				if(literal_upgrade) {
					trans->add = alpm_list_add(trans->add, spkg);
				}
				/* jump to next local package */
				break;
			} else {
				alpm_list_t *replacers;
				replacers = check_replacers(handle, lpkg, sdb);
				if(replacers) {
					trans->add = alpm_list_join(trans->add, replacers);
				}
			}
		}
	}

	return 0;
}
예제 #7
0
static alpm_list_t *check_replacers(alpm_handle_t *handle, alpm_pkg_t *lpkg,
		alpm_db_t *sdb)
{
	/* 2. search for replacers in sdb */
	alpm_list_t *replacers = NULL;
	alpm_list_t *k;
	_alpm_log(handle, ALPM_LOG_DEBUG,
			"searching for replacements for %s in %s\n",
			lpkg->name, sdb->treename);
	for(k = _alpm_db_get_pkgcache(sdb); k; k = k->next) {
		int found = 0;
		alpm_pkg_t *spkg = k->data;
		alpm_list_t *l;
		for(l = alpm_pkg_get_replaces(spkg); l; l = l->next) {
			alpm_depend_t *replace = l->data;
			/* we only want to consider literal matches at this point. */
			if(_alpm_depcmp_literal(lpkg, replace)) {
				found = 1;
				break;
			}
		}
		if(found) {
			alpm_question_replace_t question = {
				.type = ALPM_QUESTION_REPLACE_PKG,
				.replace = 0,
				.oldpkg = lpkg,
				.newpkg = spkg,
				.newdb = sdb
			};
			alpm_pkg_t *tpkg;
			/* check IgnorePkg/IgnoreGroup */
			if(alpm_pkg_should_ignore(handle, spkg)
					|| alpm_pkg_should_ignore(handle, lpkg)) {
				_alpm_log(handle, ALPM_LOG_WARNING,
						_("ignoring package replacement (%s-%s => %s-%s)\n"),
						lpkg->name, lpkg->version, spkg->name, spkg->version);
				continue;
			}

			QUESTION(handle, &question);
			if(!question.replace) {
				continue;
			}

			/* If spkg is already in the target list, we append lpkg to spkg's
			 * removes list */
			tpkg = alpm_pkg_find(handle->trans->add, spkg->name);
			if(tpkg) {
				/* sanity check, multiple repos can contain spkg->name */
				if(tpkg->origin_data.db != sdb) {
					_alpm_log(handle, ALPM_LOG_WARNING, _("cannot replace %s by %s\n"),
							lpkg->name, spkg->name);
					continue;
				}
				_alpm_log(handle, ALPM_LOG_DEBUG, "appending %s to the removes list of %s\n",
						lpkg->name, tpkg->name);
				tpkg->removes = alpm_list_add(tpkg->removes, lpkg);
				/* check the to-be-replaced package's reason field */
				if(alpm_pkg_get_reason(lpkg) == ALPM_PKG_REASON_EXPLICIT) {
					tpkg->reason = ALPM_PKG_REASON_EXPLICIT;
				}
			} else {
				/* add spkg to the target list */
				/* copy over reason */
				spkg->reason = alpm_pkg_get_reason(lpkg);
				spkg->removes = alpm_list_add(NULL, lpkg);
				_alpm_log(handle, ALPM_LOG_DEBUG,
						"adding package %s-%s to the transaction targets\n",
						spkg->name, spkg->version);
				replacers = alpm_list_add(replacers, spkg);
			}
		}
	}
	return replacers;
}

/** Search for packages to upgrade and add them to the transaction. */
int SYMEXPORT alpm_sync_sysupgrade(alpm_handle_t *handle, int enable_downgrade)
{
	alpm_list_t *i, *j;
	alpm_trans_t *trans;

	CHECK_HANDLE(handle, return -1);
	trans = handle->trans;
	ASSERT(trans != NULL, RET_ERR(handle, ALPM_ERR_TRANS_NULL, -1));
	ASSERT(trans->state == STATE_INITIALIZED, RET_ERR(handle, ALPM_ERR_TRANS_NOT_INITIALIZED, -1));

	_alpm_log(handle, ALPM_LOG_DEBUG, "checking for package upgrades\n");
	for(i = _alpm_db_get_pkgcache(handle->db_local); i; i = i->next) {
		alpm_pkg_t *lpkg = i->data;

		if(alpm_pkg_find(trans->remove, lpkg->name)) {
			_alpm_log(handle, ALPM_LOG_DEBUG, "%s is marked for removal -- skipping\n", lpkg->name);
			continue;
		}

		if(alpm_pkg_find(trans->add, lpkg->name)) {
			_alpm_log(handle, ALPM_LOG_DEBUG, "%s is already in the target list -- skipping\n", lpkg->name);
			continue;
		}

		/* Search for replacers then literal (if no replacer) in each sync database. */
		for(j = handle->dbs_sync; j; j = j->next) {
			alpm_db_t *sdb = j->data;
			alpm_list_t *replacers;

			if(!(sdb->usage & ALPM_DB_USAGE_UPGRADE)) {
				continue;
			}

			/* Check sdb */
			replacers = check_replacers(handle, lpkg, sdb);
			if(replacers) {
				trans->add = alpm_list_join(trans->add, replacers);
				/* jump to next local package */
				break;
			} else {
				alpm_pkg_t *spkg = _alpm_db_get_pkgfromcache(sdb, lpkg->name);
				if(spkg) {
					if(check_literal(handle, lpkg, spkg, enable_downgrade)) {
						trans->add = alpm_list_add(trans->add, spkg);
					}
					/* jump to next local package */
					break;
				}
			}
		}
	}

	return 0;
}
예제 #8
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;
}
예제 #9
0
파일: sync.c 프로젝트: Berticus/powaur
/* Normal -S, install packages from AUR
 * returns 0 on success, -1 on failure
 */
static int sync_targets(CURL *curl, alpm_list_t *targets)
{
	struct pw_hashdb *hashdb = build_hashdb();
	struct pkgpair pkgpair;
	struct pkgpair *pkgpair_ptr;
	struct aurpkg_t *aurpkg;
	alpm_pkg_t *lpkg;
	alpm_list_t *i;
	alpm_list_t *reinstall, *new_packages, *upgrade, *downgrade, *not_aur;
	alpm_list_t *aurpkg_list, *final_targets;
	int vercmp;
	int joined = 0, ret = 0;

	reinstall = new_packages = upgrade = downgrade = aurpkg_list = not_aur = NULL;
	final_targets = NULL;
	if (!hashdb) {
		pw_fprintf(PW_LOG_ERROR, stderr, "Failed to create hashdb\n");
		goto cleanup;
	}

	for (i = targets; i; i = i->next) {
		aurpkg_list = query_aur(curl, i->data, AUR_QUERY_INFO);
		if (!aurpkg_list) {
			not_aur = alpm_list_add(not_aur, i->data);
			goto free_aurpkg;
		}

		/* Check version string */
		pkgpair.pkgname = i->data;
		pkgpair_ptr = hash_search(hashdb->aur, &pkgpair);

		/* Locally installed AUR */
		if (pkgpair_ptr) {
			aurpkg = aurpkg_list->data;
			lpkg = pkgpair_ptr->pkg;
			vercmp = alpm_pkg_vercmp(aurpkg->version, alpm_pkg_get_version(lpkg));

			if (vercmp > 0) {
				upgrade = alpm_list_add(upgrade, i->data);
			} else if (vercmp == 0) {
				reinstall = alpm_list_add(reinstall, i->data);
			} else {
				downgrade = alpm_list_add(downgrade, i->data);
			}
		} else {
			new_packages = alpm_list_add(new_packages, i->data);
		}

free_aurpkg:
		alpm_list_free_inner(aurpkg_list, (alpm_list_fn_free) aurpkg_free);
		alpm_list_free(aurpkg_list);
	}

	if (not_aur) {
		printf("\n%sThese packages are not from the AUR:%s\n", color.bred, color.nocolor);
		print_list(not_aur);
	}

	if (downgrade) {
		printf("\n%sLocally installed but newer than AUR, ignoring:%s\n",
			   color.bcyan, color.nocolor);
		print_list(downgrade);
	}

	if (reinstall) {
		printf("\n%sReinstalling:%s\n", color.byellow, color.nocolor);
		print_list(reinstall);
	}

	if (upgrade) {
		printf("\n%sUpgrading:%s\n", color.bblue, color.nocolor);
		print_list(upgrade);
	}

	if (new_packages) {
		printf("\n%sSyncing:%s\n", color.bmag, color.nocolor);
		print_list(new_packages);
	}

	printf("\n");
	if (config->noconfirm || yesno("Do you wish to proceed?")) {
		final_targets = alpm_list_join(reinstall, upgrade);
		final_targets = alpm_list_join(final_targets, new_packages);
		joined = 1;
		ret = upgrade_pkgs(final_targets, hashdb);
	}

cleanup:
	hashdb_free(hashdb);
	alpm_list_free(downgrade);
	alpm_list_free(not_aur);

	if (joined) {
		alpm_list_free(final_targets);
	} else {
		alpm_list_free(reinstall);
		alpm_list_free(new_packages);
		alpm_list_free(upgrade);
	}

	return ret;
}
예제 #10
0
/**
 * pacman_list_concat:
 * @first: A #PacmanList.
 * @second: A #PacmanList.
 *
 * Creates a new list by appending @second to @first.
 *
 * Returns: A #PacmanList composed of @first and @second. Do not use or free @first or @second afterwards.
 */
PacmanList *pacman_list_concat (PacmanList *first, PacmanList *second) {
	return alpm_list_join (first, second);
}
예제 #11
0
파일: remove.c 프로젝트: JohnFrazier/pacman
/**
 * @brief Remove a package's files, optionally skipping its replacement's
 * files.
 *
 * @param handle the context handle
 * @param oldpkg package to remove
 * @param newpkg package to replace \a oldpkg (optional)
 * @param targ_count current index within the transaction (1-based)
 * @param pkg_count the number of packages affected by the transaction
 *
 * @return 0 on success, -1 if alpm lacks permission to delete some of the
 * files, >0 the number of files alpm was unable to delete
 */
static int remove_package_files(alpm_handle_t *handle,
		alpm_pkg_t *oldpkg, alpm_pkg_t *newpkg,
		size_t targ_count, size_t pkg_count)
{
	alpm_list_t *skip_remove;
	alpm_filelist_t *filelist;
	size_t i;
	int err = 0;
	int nosave = handle->trans->flags & ALPM_TRANS_FLAG_NOSAVE;

	if(newpkg) {
		alpm_filelist_t *newfiles;
		alpm_list_t *b;
		skip_remove = alpm_list_join(
				alpm_list_strdup(handle->trans->skip_remove),
				alpm_list_strdup(handle->noupgrade));
		/* Add files in the NEW backup array to the skip_remove array
		 * so this removal operation doesn't kill them */
		/* old package backup list */
		newfiles = alpm_pkg_get_files(newpkg);
		for(b = alpm_pkg_get_backup(newpkg); b; b = b->next) {
			const alpm_backup_t *backup = b->data;
			/* safety check (fix the upgrade026 pactest) */
			if(!alpm_filelist_contains(newfiles, backup->name)) {
				continue;
			}
			_alpm_log(handle, ALPM_LOG_DEBUG, "adding %s to the skip_remove array\n",
					backup->name);
			skip_remove = alpm_list_add(skip_remove, strdup(backup->name));
		}
	} else {
		skip_remove = alpm_list_strdup(handle->trans->skip_remove);
	}

	filelist = alpm_pkg_get_files(oldpkg);
	for(i = 0; i < filelist->count; i++) {
		alpm_file_t *file = filelist->files + i;
		if(!can_remove_file(handle, file, skip_remove)) {
			_alpm_log(handle, ALPM_LOG_DEBUG,
					"not removing package '%s', can't remove all files\n",
					oldpkg->name);
			FREELIST(skip_remove);
			RET_ERR(handle, ALPM_ERR_PKG_CANT_REMOVE, -1);
		}
	}

	_alpm_log(handle, ALPM_LOG_DEBUG, "removing %zd files\n", filelist->count);

	if(!newpkg) {
		/* init progress bar, but only on true remove transactions */
		PROGRESS(handle, ALPM_PROGRESS_REMOVE_START, oldpkg->name, 0,
				pkg_count, targ_count);
	}

	/* iterate through the list backwards, unlinking files */
	for(i = filelist->count; i > 0; i--) {
		alpm_file_t *file = filelist->files + i - 1;
		if(unlink_file(handle, oldpkg, newpkg, file, skip_remove, nosave) < 0) {
			err++;
		}

		if(!newpkg) {
			/* update progress bar after each file */
			int percent = ((filelist->count - i) * 100) / filelist->count;
			PROGRESS(handle, ALPM_PROGRESS_REMOVE_START, oldpkg->name,
					percent, pkg_count, targ_count);
		}
	}
	FREELIST(skip_remove);

	if(!newpkg) {
		/* set progress to 100% after we finish unlinking files */
		PROGRESS(handle, ALPM_PROGRESS_REMOVE_START, oldpkg->name, 100,
				pkg_count, targ_count);
	}

	return err;
}