-#include "user.h"
-
-int satisfy_dependencies_for(opkg_conf_t *conf, pkg_t *pkg);
-static int verify_pkg_installable(opkg_conf_t *conf, pkg_t *pkg);
-static int unpack_pkg_control_files(opkg_conf_t *conf, pkg_t *pkg);
-
-static int prerm_upgrade_old_pkg(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg);
-static int prerm_upgrade_old_pkg_unwind(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg);
-static int prerm_deconfigure_conflictors(opkg_conf_t *conf, pkg_t *pkg, pkg_vec_t *conflictors);
-static int prerm_deconfigure_conflictors_unwind(opkg_conf_t *conf, pkg_t *pkg, pkg_vec_t *conflictors);
-static int preinst_configure(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg);
-static int preinst_configure_unwind(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg);
-static int check_data_file_clashes(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg);
-static int check_data_file_clashes_change(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg);
-static int check_data_file_clashes_unwind(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg);
-static int backup_modified_conffiles(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg);
-static int backup_modified_conffiles_unwind(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg);
-static int postrm_upgrade_old_pkg(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg);
-static int postrm_upgrade_old_pkg_unwind(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg);
-
-static int remove_obsolesced_files(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg);
-static int install_maintainer_scripts(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg);
-static int remove_disappeared(opkg_conf_t *conf, pkg_t *pkg);
-static int install_data_files(opkg_conf_t *conf, pkg_t *pkg);
-static int resolve_conffiles(opkg_conf_t *conf, pkg_t *pkg);
-
-static int cleanup_temporary_files(opkg_conf_t *conf, pkg_t *pkg);
-
-static int user_prefers_old_conffile(const char *file, const char *backup);
-
-static char *backup_filename_alloc(const char *file_name);
-static int backup_make_backup(opkg_conf_t *conf, const char *file_name);
-static int backup_exists_for(const char *file_name);
-static int backup_remove(const char *file_name);
-
-
-int opkg_install_from_file(opkg_conf_t *conf, const char *filename)
-{
- int err, cmp;
- pkg_t *pkg, *old;
- char *old_version, *new_version;
-
- pkg = pkg_new();
- if (pkg == NULL) {
- return ENOMEM;
- }
-
- err = pkg_init_from_file(pkg, filename);
- if (err) {
- return err;
- }
-
- if (!pkg->architecture) {
- opkg_message(conf, OPKG_ERROR, "Package %s has no Architecture defined.\n", pkg->name);
- return -EINVAL;
- }
-
- /* XXX: CLEANUP: hash_insert_pkg has a nasty side effect of possibly
- freeing the pkg that we pass in. It might be nice to clean this up
- if possible. */
- pkg = hash_insert_pkg(&conf->pkg_hash, pkg, 1,conf);
- old = pkg_hash_fetch_installed_by_name(&conf->pkg_hash, pkg->name);
-
- pkg->local_filename = strdup(filename);
-
- if (old) {
- old_version = pkg_version_str_alloc(old);
- new_version = pkg_version_str_alloc(pkg);
-
- cmp = pkg_compare_versions(old, pkg);
- if ( (conf->force_downgrade==1) && (cmp > 0) ){ /* We've been asked to allow downgrade and version is precedent */
- cmp = -1 ; /* then we force opkg to downgrade */
- /* We need to use a value < 0 because in the 0 case we are asking to */
- /* reinstall, and some check could fail asking the "force-reinstall" option */
- }
- if (cmp > 0) {
- opkg_message(conf, OPKG_NOTICE,
- "Not downgrading package %s on %s from %s to %s.\n",
- old->name, old->dest->name, old_version, new_version);
- pkg->state_want = SW_DEINSTALL;
- pkg->state_flag |= SF_OBSOLETE;
- free(old_version);
- free(new_version);
- return 0;
- } else {
- free(old_version);
- free(new_version);
- }
- }
-
- opkg_message(conf, OPKG_DEBUG2,"Function: %s calling opkg_install_pkg \n",__FUNCTION__);
- return opkg_install_pkg(conf, pkg,0);
-}
-
-opkg_error_t opkg_install_by_name(opkg_conf_t *conf, const char *pkg_name)
-{
- int cmp, err;
- pkg_t *old, *new;
- char *old_version, *new_version;
-
- opkg_message(conf, OPKG_DEBUG2, " Getting old from pkg_hash_fetch \n" );
- old = pkg_hash_fetch_installed_by_name(&conf->pkg_hash, pkg_name);
- if ( old )
- opkg_message(conf, OPKG_DEBUG2, " Old versions from pkg_hash_fetch %s \n", old->version );
-
- opkg_message(conf, OPKG_DEBUG2, " Getting new from pkg_hash_fetch \n" );
- new = pkg_hash_fetch_best_installation_candidate_by_name(conf, pkg_name, &err);
- if ( new )
- opkg_message(conf, OPKG_DEBUG2, " New versions from pkg_hash_fetch %s \n", new->version );
-
-/* Pigi Basically here is broken the version stuff.
- What's happening is that nothing provide the version to differents
- functions, so the returned struct is always the latest.
- That's why the install by name don't work.
-*/
- opkg_message(conf, OPKG_DEBUG2, " Versions from pkg_hash_fetch in %s ", __FUNCTION__ );
-
- if ( old )
- opkg_message(conf, OPKG_DEBUG2, " old %s ", old->version );
- if ( new )
- opkg_message(conf, OPKG_DEBUG2, " new %s ", new->version );
- opkg_message(conf, OPKG_DEBUG2, " \n");
-
- if (new == NULL) {
- if (err)
- return err;
- else
- return OPKG_PKG_HAS_NO_CANDIDATE;
- }
-
- new->state_flag |= SF_USER;
- if (old) {
- old_version = pkg_version_str_alloc(old);
- new_version = pkg_version_str_alloc(new);
-
- cmp = pkg_compare_versions(old, new);
- if ( (conf->force_downgrade==1) && (cmp > 0) ){ /* We've been asked to allow downgrade and version is precedent */
- opkg_message(conf, OPKG_DEBUG, " Forcing downgrade \n");
- cmp = -1 ; /* then we force opkg to downgrade */
- /* We need to use a value < 0 because in the 0 case we are asking to */
- /* reinstall, and some check could fail asking the "force-reinstall" option */
- }
- opkg_message(conf, OPKG_DEBUG,
- "Comparing visible versions of pkg %s:"
- "\n\t%s is installed "
- "\n\t%s is available "
- "\n\t%d was comparison result\n",
- pkg_name, old_version, new_version, cmp);
- if (cmp == 0 && !conf->force_reinstall) {
- opkg_message(conf, OPKG_NOTICE,
- "Package %s (%s) installed in %s is up to date.\n",
- old->name, old_version, old->dest->name);
- free(old_version);
- free(new_version);
- return 0;
- } else if (cmp > 0) {
- opkg_message(conf, OPKG_NOTICE,
- "Not downgrading package %s on %s from %s to %s.\n",
- old->name, old->dest->name, old_version, new_version);
- free(old_version);
- free(new_version);
- return 0;
- } else if (cmp < 0) {
- new->dest = old->dest;
- old->state_want = SW_DEINSTALL; /* Here probably the problem for bug 1277 */
- }
- }
-
- /* XXX: CLEANUP: The error code of opkg_install_by_name is really
- supposed to be an opkg_error_t, but opkg_install_pkg could
- return any kind of integer, (might be errno from a syscall,
- etc.). This is a real mess and will need to be cleaned up if
- anyone ever wants to make a nice libopkg. */
-
- opkg_message(conf, OPKG_DEBUG2,"Function: %s calling opkg_install_pkg \n",__FUNCTION__);
- return opkg_install_pkg(conf, new,0);
-}
-
-opkg_error_t opkg_install_multi_by_name(opkg_conf_t *conf, const char *pkg_name)
-{
- abstract_pkg_vec_t *providers = pkg_hash_fetch_all_installation_candidates (&conf->pkg_hash, pkg_name);
- int i;
- opkg_error_t err;
- abstract_pkg_t *ppkg ;
-
- if (providers == NULL)
- return OPKG_PKG_HAS_NO_CANDIDATE;
-
- for (i = 0; i < providers->len; i++) {
- ppkg = abstract_pkg_vec_get(providers, i);
- opkg_message(conf, OPKG_DEBUG2,"Function: %s calling opkg_install_by_name %d \n",__FUNCTION__, i);
- err = opkg_install_by_name(conf, ppkg->name);
- if (err)
- return err;
-/* XXX Maybe ppkg should be freed ? */
- }
- return 0;
-}
-
-/*
- * Walk dependence graph starting with pkg, collect packages to be
- * installed into pkgs_needed, in dependence order.
- */
-int pkg_mark_dependencies_for_installation(opkg_conf_t *conf, pkg_t *pkg, pkg_vec_t *pkgs_needed)
-{
- int i, err;
- pkg_vec_t *depends = pkg_vec_alloc();
- char **unresolved = NULL;
- int ndepends;
-
- ndepends = pkg_hash_fetch_unsatisfied_dependencies(conf,
- pkg, depends,
- &unresolved);
-
- if (unresolved) {
- opkg_message(conf, OPKG_ERROR,
- "%s: Cannot satisfy the following dependencies for %s:\n\t",
- conf->force_depends ? "Warning" : "ERROR", pkg->name);
- while (*unresolved) {
- opkg_message(conf, OPKG_ERROR, " %s", *unresolved);
- unresolved++;
- }
- opkg_message(conf, OPKG_ERROR, "\n");
- if (! conf->force_depends) {
- opkg_message(conf, OPKG_INFO,
- "This could mean that your package list is out of date or that the packages\n"
- "mentioned above do not yet exist (try 'opkg update'). To proceed in spite\n"
- "of this problem try again with the '-force-depends' option.\n");
- pkg_vec_free(depends);
- return OPKG_PKG_DEPS_UNSATISFIED;
- }
- }
-
- if (ndepends <= 0) {
- pkg_vec_free(depends);
- return 0;
- }
-
- for (i = 0; i < depends->len; i++) {
- pkg_t *dep = depends->pkgs[i];
- /* The package was uninstalled when we started, but another
- dep earlier in this loop may have depended on it and pulled
- it in, so check first. */
- if ((dep->state_status != SS_INSTALLED)
- && (dep->state_status != SS_UNPACKED)
- && (dep->state_want != SW_INSTALL)) {
-
- /* Mark packages as to-be-installed */
- dep->state_want = SW_INSTALL;
-
- /* Dependencies should be installed the same place as pkg */
- if (dep->dest == NULL) {
- dep->dest = pkg->dest;
- }
-
- err = pkg_mark_dependencies_for_installation(conf, dep, pkgs_needed);
- if (err) {
- pkg_vec_free(depends);
- return err;
- }
- }
- }
- if (pkgs_needed)
- pkg_vec_insert(pkgs_needed, pkg);
-
- pkg_vec_free(depends);
-
- return 0;
-}
-#if 0
-int name_mark_dependencies_for_installation(opkg_conf_t *conf, const char *pkg_name, pkg_vec_t *pkgs_needed)
-{
- int cmp;
- pkg_t *old, *new;
- char *old_version, *new_version;
-
- old = pkg_hash_fetch_installed_by_name(&conf->pkg_hash, pkg_name);
-
- new = pkg_hash_fetch_best_installation_candidate_by_name(conf, pkg_name);
- if (new == NULL) {
- return OPKG_PKG_HAS_NO_CANDIDATE;
- }
- if (old) {
- old_version = pkg_version_str_alloc(old);
- new_version = pkg_version_str_alloc(new);
-
- cmp = pkg_compare_versions(old, new);
- if ( (conf->force_downgrade==1) && (cmp > 0) ){ /* We've been asked to allow downgrade and version is precedent */
- opkg_message(conf, OPKG_DEBUG, " Forcing downgrade ");
- cmp = -1 ; /* then we force opkg to downgrade */
- /* We need to use a value < 0 because in the 0 case we are asking to */
- /* reinstall, and some check could fail asking the "force-reinstall" option */
- }
- opkg_message(conf, OPKG_DEBUG,
- "comparing visible versions of pkg %s:"
- "\n\t%s is installed "
- "\n\t%s is available "
- "\n\t%d was comparison result\n",
- pkg_name, old_version, new_version, cmp);
- if (cmp == 0 && !conf->force_reinstall) {
- opkg_message(conf, OPKG_NOTICE,
- "Package %s (%s) installed in %s is up to date.\n",
- old->name, old_version, old->dest->name);
- free(old_version);
- free(new_version);
- return 0;
- } else if (cmp > 0) {
- opkg_message(conf, OPKG_NOTICE,
- "Not downgrading package %s on %s from %s to %s.\n",
- old->name, old->dest->name, old_version, new_version);
- free(old_version);
- free(new_version);
- return 0;
- } else if (cmp < 0) {
- new->dest = old->dest;
- old->state_want = SW_DEINSTALL;
- old->state_flag |= SF_OBSOLETE;
- }
- }
- return pkg_mark_dependencies_for_installation(conf, new, pkgs_needed);
-}
-
-#endif