summaryrefslogtreecommitdiffstats
path: root/libopkg
diff options
context:
space:
mode:
Diffstat (limited to 'libopkg')
-rw-r--r--libopkg/opkg_install.c1191
-rw-r--r--libopkg/opkg_install.h10
2 files changed, 516 insertions, 685 deletions
diff --git a/libopkg/opkg_install.c b/libopkg/opkg_install.c
index 3ee7242..c75a8d4 100644
--- a/libopkg/opkg_install.c
+++ b/libopkg/opkg_install.c
@@ -21,9 +21,6 @@
#include <glob.h>
#include <time.h>
#include <signal.h>
-#ifndef __USE_GNU
-typedef void (*sighandler_t)(int);
-#endif
#include "pkg.h"
#include "pkg_hash.h"
@@ -46,269 +43,8 @@ typedef void (*sighandler_t)(int);
#include "user.h"
#include "libbb/libbb.h"
-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 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();
-
- err = pkg_init_from_file(conf, 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);
-
- 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 = 0;
- 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 */
- }
- free(old_version);
- free(new_version);
- }
-
- /* 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;
-}
-
-int satisfy_dependencies_for(opkg_conf_t *conf, pkg_t *pkg)
+static int
+satisfy_dependencies_for(opkg_conf_t *conf, pkg_t *pkg)
{
int i, err;
pkg_vec_t *depends = pkg_vec_alloc();
@@ -377,25 +113,8 @@ int satisfy_dependencies_for(opkg_conf_t *conf, pkg_t *pkg)
return 0;
}
-
-/* check all packages have their dependences satisfied, e.g., in case an upgraded package split */
-int opkg_satisfy_all_dependences(opkg_conf_t *conf)
-{
- if (conf->nodeps == 0) {
- int i;
- pkg_vec_t *installed = pkg_vec_alloc();
- pkg_hash_fetch_all_installed(&conf->pkg_hash, installed);
- for (i = 0; i < installed->len; i++) {
- pkg_t *pkg = installed->pkgs[i];
- satisfy_dependencies_for(conf, pkg);
- }
- pkg_vec_free(installed);
- }
- return 0;
-}
-
-
-static int check_conflicts_for(opkg_conf_t *conf, pkg_t *pkg)
+static int
+check_conflicts_for(opkg_conf_t *conf, pkg_t *pkg)
{
int i;
pkg_vec_t *conflicts = NULL;
@@ -425,7 +144,8 @@ static int check_conflicts_for(opkg_conf_t *conf, pkg_t *pkg)
return 0;
}
-static int update_file_ownership(opkg_conf_t *conf, pkg_t *new_pkg, pkg_t *old_pkg)
+static int
+update_file_ownership(opkg_conf_t *conf, pkg_t *new_pkg, pkg_t *old_pkg)
{
str_list_t *new_list = pkg_get_installed_files(conf, new_pkg);
str_list_elt_t *iter, *niter;
@@ -458,7 +178,8 @@ static int update_file_ownership(opkg_conf_t *conf, pkg_t *new_pkg, pkg_t *old_p
return 0;
}
-static int verify_pkg_installable(opkg_conf_t *conf, pkg_t *pkg)
+static int
+verify_pkg_installable(opkg_conf_t *conf, pkg_t *pkg)
{
/* XXX: FEATURE: Anything else needed here? Maybe a check on free space? */
@@ -491,7 +212,8 @@ static int verify_pkg_installable(opkg_conf_t *conf, pkg_t *pkg)
return 0;
}
-static int unpack_pkg_control_files(opkg_conf_t *conf, pkg_t *pkg)
+static int
+unpack_pkg_control_files(opkg_conf_t *conf, pkg_t *pkg)
{
int err;
char *conffiles_file_name;
@@ -662,7 +384,8 @@ pkg_remove_orphan_dependent(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg)
}
/* returns number of installed replacees */
-int pkg_get_installed_replacees(opkg_conf_t *conf, pkg_t *pkg, pkg_vec_t *installed_replacees)
+static int
+pkg_get_installed_replacees(opkg_conf_t *conf, pkg_t *pkg, pkg_vec_t *installed_replacees)
{
abstract_pkg_t **replaces = pkg->replaces;
int replaces_count = pkg->replaces_count;
@@ -684,7 +407,8 @@ int pkg_get_installed_replacees(opkg_conf_t *conf, pkg_t *pkg, pkg_vec_t *instal
return installed_replacees->len;
}
-int pkg_remove_installed_replacees(opkg_conf_t *conf, pkg_vec_t *replacees)
+static int
+pkg_remove_installed_replacees(opkg_conf_t *conf, pkg_vec_t *replacees)
{
int i;
int replaces_count = replacees->len;
@@ -700,7 +424,8 @@ int pkg_remove_installed_replacees(opkg_conf_t *conf, pkg_vec_t *replacees)
}
/* to unwind the removal: make sure they are installed */
-int pkg_remove_installed_replacees_unwind(opkg_conf_t *conf, pkg_vec_t *replacees)
+static int
+pkg_remove_installed_replacees_unwind(opkg_conf_t *conf, pkg_vec_t *replacees)
{
int i, err;
int replaces_count = replacees->len;
@@ -717,7 +442,8 @@ int pkg_remove_installed_replacees_unwind(opkg_conf_t *conf, pkg_vec_t *replacee
}
/* compares versions of pkg and old_pkg, returns 0 if OK to proceed with installation of pkg, 1 otherwise */
-static int opkg_install_check_downgrade(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg, int message)
+static int
+opkg_install_check_downgrade(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg, int message)
{
if (old_pkg) {
char message_out[15];
@@ -779,303 +505,9 @@ static int opkg_install_check_downgrade(opkg_conf_t *conf, pkg_t *pkg, pkg_t *ol
}
}
-/**
- * @brief Really install a pkg_t
- */
-int opkg_install_pkg(opkg_conf_t *conf, pkg_t *pkg, int from_upgrade)
-{
- int err = 0;
- int message = 0;
- pkg_t *old_pkg = NULL;
- pkg_vec_t *replacees;
- abstract_pkg_t *ab_pkg = NULL;
- int old_state_flag;
- char* file_md5;
-#ifdef HAVE_SHA256
- char* file_sha256;
-#endif
-
- if ( from_upgrade )
- message = 1; /* Coming from an upgrade, and should change the output message */
-
- if (!pkg) {
- opkg_message(conf, OPKG_ERROR,
- "INTERNAL ERROR: null pkg passed to opkg_install_pkg\n");
- return OPKG_INSTALL_ERR_INTERNAL;
- }
-
- opkg_message(conf, OPKG_DEBUG2, "Function: %s calling pkg_arch_supported %s \n", __FUNCTION__, __FUNCTION__);
-
- if (!pkg_arch_supported(conf, pkg)) {
- opkg_message(conf, OPKG_ERROR, "INTERNAL ERROR: architecture %s for pkg %s is unsupported.\n",
- pkg->architecture, pkg->name);
- return OPKG_INSTALL_ERR_INTERNAL;
- }
- if (pkg->state_status == SS_INSTALLED && conf->force_reinstall == 0 && conf->nodeps == 0) {
- err = satisfy_dependencies_for(conf, pkg);
- if (err) { return OPKG_INSTALL_ERR_DEPENDENCIES; }
-
- opkg_message(conf, OPKG_NOTICE,
- "Package %s is already installed in %s.\n",
- pkg->name, pkg->dest->name);
- return 0;
- }
-
- if (pkg->dest == NULL) {
- pkg->dest = conf->default_dest;
- }
-
- old_pkg = pkg_hash_fetch_installed_by_name(&conf->pkg_hash, pkg->name);
-
- err = opkg_install_check_downgrade(conf, pkg, old_pkg, message);
- if (err) { return OPKG_INSTALL_ERR_NO_DOWNGRADE; }
-
- pkg->state_want = SW_INSTALL;
- if (old_pkg){
- old_pkg->state_want = SW_DEINSTALL; /* needed for check_data_file_clashes of dependences */
- }
-
-
- /* Abhaya: conflicts check */
- err = check_conflicts_for(conf, pkg);
- if (err) { return OPKG_INSTALL_ERR_CONFLICTS; }
-
- /* this setup is to remove the upgrade scenario in the end when
- installing pkg A, A deps B & B deps on A. So both B and A are
- installed. Then A's installation is started resulting in an
- uncecessary upgrade */
- if (pkg->state_status == SS_INSTALLED
- && conf->force_reinstall == 0) return 0;
-
- err = verify_pkg_installable(conf, pkg);
- if (err) { return OPKG_INSTALL_ERR_NO_SPACE; }
-
- if (pkg->local_filename == NULL) {
- err = opkg_download_pkg(conf, pkg, conf->tmp_dir);
- if (err) {
- opkg_message(conf, OPKG_ERROR,
- "Failed to download %s. Perhaps you need to run 'opkg update'?\n",
- pkg->name);
- return OPKG_INSTALL_ERR_DOWNLOAD;
- }
- }
-
- /* check that the repository is valid */
- #if defined(HAVE_GPGME) || defined(HAVE_OPENSSL)
- char *list_file_name, *sig_file_name, *lists_dir;
-
- /* check to ensure the package has come from a repository */
- if (conf->check_signature && pkg->src)
- {
- sprintf_alloc (&lists_dir, "%s",
- (conf->restrict_to_default_dest)
- ? conf->default_dest->lists_dir
- : conf->lists_dir);
- sprintf_alloc (&list_file_name, "%s/%s", lists_dir, pkg->src->name);
- sprintf_alloc (&sig_file_name, "%s/%s.sig", lists_dir, pkg->src->name);
-
- if (file_exists (sig_file_name))
- {
- if (opkg_verify_file (conf, list_file_name, sig_file_name)){
- opkg_message(conf, OPKG_ERROR, "Failed to verify the signature of: %s\n",
- list_file_name);
- return OPKG_INSTALL_ERR_SIGNATURE;
- }
- }else{
- opkg_message(conf, OPKG_ERROR, "Signature file is missing. "
- "Perhaps you need to run 'opkg update'?\n");
- return OPKG_INSTALL_ERR_SIGNATURE;
- }
-
- free (lists_dir);
- free (list_file_name);
- free (sig_file_name);
- }
- #endif
-
- /* Check for md5 values */
- if (pkg->md5sum)
- {
- file_md5 = file_md5sum_alloc(pkg->local_filename);
- if (file_md5 && strcmp(file_md5, pkg->md5sum))
- {
- opkg_message(conf, OPKG_ERROR,
- "Package %s md5sum mismatch. Either the opkg or the package index are corrupt. Try 'opkg update'.\n",
- pkg->name);
- free(file_md5);
- return OPKG_INSTALL_ERR_MD5;
- }
- if (file_md5)
- free(file_md5);
- }
-
-#ifdef HAVE_SHA256
- /* Check for sha256 value */
- if(pkg->sha256sum)
- {
- file_sha256 = file_sha256sum_alloc(pkg->local_filename);
- if (file_sha256 && strcmp(file_sha256, pkg->sha256sum))
- {
- opkg_message(conf, OPKG_ERROR,
- "Package %s sha256sum mismatch. Either the opkg or the package index are corrupt. Try 'opkg update'.\n",
- pkg->name);
- free(file_sha256);
- return OPKG_INSTALL_ERR_SHA256;
- }
- if (file_sha256)
- free(file_sha256);
- }
-#endif
-
- if (pkg->tmp_unpack_dir == NULL) {
- unpack_pkg_control_files(conf, pkg);
- }
-
- /* We should update the filelist here, so that upgrades of packages that split will not fail. -Jamey 27-MAR-03 */
-/* Pigi: check if it will pass from here when replacing. It seems to fail */
-/* That's rather strange that files don't change owner. Investigate !!!!!!*/
- err = update_file_ownership(conf, pkg, old_pkg);
- if (err) { return OPKG_ERR_UNKNOWN; }
-
- if (conf->nodeps == 0) {
- err = satisfy_dependencies_for(conf, pkg);
- if (err) { return OPKG_INSTALL_ERR_DEPENDENCIES; }
- if (pkg->state_status == SS_UNPACKED)
- /* Circular dependency has installed it for us. */
- return 0;
- }
-
- replacees = pkg_vec_alloc();
- pkg_get_installed_replacees(conf, pkg, replacees);
-
- /* this next section we do with SIGINT blocked to prevent inconsistency between opkg database and filesystem */
- {
- sigset_t newset, oldset;
-
- sigemptyset(&newset);
- sigaddset(&newset, SIGINT);
- sigprocmask(SIG_BLOCK, &newset, &oldset);
-
- opkg_state_changed++;
- pkg->state_flag |= SF_FILELIST_CHANGED;
-
- if (old_pkg)
- pkg_remove_orphan_dependent(conf, pkg, old_pkg);
-
- /* XXX: BUG: we really should treat replacement more like an upgrade
- * Instead, we're going to remove the replacees
- */
- err = pkg_remove_installed_replacees(conf, replacees);
- if (err) goto UNWIND_REMOVE_INSTALLED_REPLACEES;
- err = prerm_upgrade_old_pkg(conf, pkg, old_pkg);
- if (err) goto UNWIND_PRERM_UPGRADE_OLD_PKG;
-
- err = prerm_deconfigure_conflictors(conf, pkg, replacees);
- if (err) goto UNWIND_PRERM_DECONFIGURE_CONFLICTORS;
-
- err = preinst_configure(conf, pkg, old_pkg);
- if (err) goto UNWIND_PREINST_CONFIGURE;
-
- err = backup_modified_conffiles(conf, pkg, old_pkg);
- if (err) goto UNWIND_BACKUP_MODIFIED_CONFFILES;
-
- err = check_data_file_clashes(conf, pkg, old_pkg);
- if (err) goto UNWIND_CHECK_DATA_FILE_CLASHES;
-
- err = postrm_upgrade_old_pkg(conf, pkg, old_pkg);
- if (err) goto UNWIND_POSTRM_UPGRADE_OLD_PKG;
-
- if (conf->noaction) return 0;
-
- /* point of no return: no unwinding after this */
- if (old_pkg && !conf->force_reinstall) {
- old_pkg->state_want = SW_DEINSTALL;
-
- if (old_pkg->state_flag & SF_NOPRUNE) {
- opkg_message(conf, OPKG_INFO,
- " not removing obsolesced files because package marked noprune\n");
- } else {
- opkg_message(conf, OPKG_INFO,
- " removing obsolesced files\n");
- remove_obsolesced_files(conf, pkg, old_pkg);
- }
- /* removing files from old package, to avoid ghost files */
- remove_data_files_and_list(conf, old_pkg);
-/* Pigi : It should be better to remove also maintainer and postrem scripts here, just in case*/
- remove_maintainer_scripts_except_postrm(conf, old_pkg);
- remove_postrm(conf, old_pkg);
-/* Pigi */
-
- }
-
-
- opkg_message(conf, OPKG_INFO,
- " installing maintainer scripts\n");
- install_maintainer_scripts(conf, pkg, old_pkg);
-
- /* the following just returns 0 */
- remove_disappeared(conf, pkg);
-
- opkg_message(conf, OPKG_INFO,
- " installing data files\n");
- install_data_files(conf, pkg);
-
-/* read comments from function for detail but I will execute this here as all other tests are ok.*/
- err = check_data_file_clashes_change(conf, pkg, old_pkg);
-
- opkg_message(conf, OPKG_INFO,
- " resolving conf files\n");
- resolve_conffiles(conf, pkg);
-
- pkg->state_status = SS_UNPACKED;
- old_state_flag = pkg->state_flag;
- pkg->state_flag &= ~SF_PREFER;
- opkg_message(conf, OPKG_DEBUG, " pkg=%s old_state_flag=%x state_flag=%x\n", pkg->name, old_state_flag, pkg->state_flag);
-
- if (old_pkg && !conf->force_reinstall) {
- old_pkg->state_status = SS_NOT_INSTALLED;
- }
-
- time(&pkg->installed_time);
-
- ab_pkg = pkg->parent;
- if (ab_pkg)
- ab_pkg->state_status = pkg->state_status;
-
- opkg_message(conf, OPKG_INFO, "Done.\n");
-
- sigprocmask(SIG_UNBLOCK, &newset, &oldset);
- pkg_vec_free (replacees);
- return 0;
-
-
- UNWIND_POSTRM_UPGRADE_OLD_PKG:
- postrm_upgrade_old_pkg_unwind(conf, pkg, old_pkg);
- UNWIND_CHECK_DATA_FILE_CLASHES:
- check_data_file_clashes_unwind(conf, pkg, old_pkg);
- UNWIND_BACKUP_MODIFIED_CONFFILES:
- backup_modified_conffiles_unwind(conf, pkg, old_pkg);
- UNWIND_PREINST_CONFIGURE:
- preinst_configure_unwind(conf, pkg, old_pkg);
- UNWIND_PRERM_DECONFIGURE_CONFLICTORS:
- prerm_deconfigure_conflictors_unwind(conf, pkg, replacees);
- UNWIND_PRERM_UPGRADE_OLD_PKG:
- prerm_upgrade_old_pkg_unwind(conf, pkg, old_pkg);
- UNWIND_REMOVE_INSTALLED_REPLACEES:
- pkg_remove_installed_replacees_unwind(conf, replacees);
-
- opkg_message(conf, OPKG_INFO,
- "Failed.\n");
-
- sigprocmask(SIG_UNBLOCK, &newset, &oldset);
-
- pkg_vec_free (replacees);
- return OPKG_ERR_UNKNOWN;
- }
-}
-
-static int prerm_upgrade_old_pkg(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg)
+static int
+prerm_upgrade_old_pkg(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg)
{
/* DPKG_INCOMPATIBILITY:
dpkg does some things here that we don't do yet. Do we care?
@@ -1090,7 +522,8 @@ static int prerm_upgrade_old_pkg(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg)
return 0;
}
-static int prerm_upgrade_old_pkg_unwind(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)
{
/* DPKG_INCOMPATIBILITY:
dpkg does some things here that we don't do yet. Do we care?
@@ -1099,7 +532,8 @@ static int prerm_upgrade_old_pkg_unwind(opkg_conf_t *conf, pkg_t *pkg, pkg_t *ol
return 0;
}
-static int prerm_deconfigure_conflictors(opkg_conf_t *conf, pkg_t *pkg, pkg_vec_t *conflictors)
+static int
+prerm_deconfigure_conflictors(opkg_conf_t *conf, pkg_t *pkg, pkg_vec_t *conflictors)
{
/* DPKG_INCOMPATIBILITY:
dpkg does some things here that we don't do yet. Do we care?
@@ -1125,7 +559,8 @@ static int prerm_deconfigure_conflictors(opkg_conf_t *conf, pkg_t *pkg, pkg_vec_
return 0;
}
-static int prerm_deconfigure_conflictors_unwind(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)
{
/* DPKG_INCOMPATIBILITY: dpkg does some things here that we don't
do yet. Do we care? (See prerm_deconfigure_conflictors for
@@ -1133,7 +568,8 @@ static int prerm_deconfigure_conflictors_unwind(opkg_conf_t *conf, pkg_t *pkg, p
return 0;
}
-static int preinst_configure(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg)
+static int
+preinst_configure(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg)
{
int err;
char *preinst_args;
@@ -1162,7 +598,8 @@ static int preinst_configure(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg)
return 0;
}
-static int preinst_configure_unwind(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)
{
/* DPKG_INCOMPATIBILITY:
dpkg does the following error unwind, should we?
@@ -1173,7 +610,65 @@ static int preinst_configure_unwind(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pk
return 0;
}
-static int backup_modified_conffiles(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg)
+static char *
+backup_filename_alloc(const char *file_name)
+{
+ char *backup;
+
+ sprintf_alloc(&backup, "%s%s", file_name, OPKG_BACKUP_SUFFIX);
+
+ return backup;
+}
+
+
+static int
+backup_make_backup(opkg_conf_t *conf, const char *file_name)
+{
+ int err;
+ char *backup;
+
+ backup = backup_filename_alloc(file_name);
+ err = file_copy(file_name, backup);
+ if (err) {
+ opkg_message(conf, OPKG_ERROR,
+ "%s: Failed to copy %s to %s\n",
+ __FUNCTION__, file_name, backup);
+ }
+
+ free(backup);
+
+ return err;
+}
+
+static int
+backup_exists_for(const char *file_name)
+{
+ int ret;
+ char *backup;
+
+ backup = backup_filename_alloc(file_name);
+
+ ret = file_exists(backup);
+
+ free(backup);
+
+ return ret;
+}
+
+static int
+backup_remove(const char *file_name)
+{
+ char *backup;
+
+ backup = backup_filename_alloc(file_name);
+ unlink(backup);
+ free(backup);
+
+ return 0;
+}
+
+static int
+backup_modified_conffiles(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg)
{
int err;
conffile_list_elt_t *iter;
@@ -1222,7 +717,8 @@ static int backup_modified_conffiles(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_p
return 0;
}
-static int backup_modified_conffiles_unwind(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)
{
conffile_list_elt_t *iter;
@@ -1240,7 +736,8 @@ static int backup_modified_conffiles_unwind(opkg_conf_t *conf, pkg_t *pkg, pkg_t
}
-static int check_data_file_clashes(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)
{
/* DPKG_INCOMPATIBILITY:
opkg takes a slightly different approach than dpkg at this
@@ -1334,7 +831,8 @@ static int check_data_file_clashes(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg
return clashes;
}
-static int check_data_file_clashes_change(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)
{
/* Basically that's the worst hack I could do to be able to change ownership of
file list, but, being that we have no way to unwind the mods, due to structure
@@ -1395,13 +893,15 @@ static int check_data_file_clashes_change(opkg_conf_t *conf, pkg_t *pkg, pkg_t *
return clashes;
}
-static int check_data_file_clashes_unwind(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)
{
/* Nothing to do since check_data_file_clashes doesn't change state */
return 0;
}
-static int postrm_upgrade_old_pkg(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)
{
/* DPKG_INCOMPATIBILITY: dpkg does the following here, should we?
1. If the package is being upgraded, call
@@ -1413,7 +913,8 @@ static int postrm_upgrade_old_pkg(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg)
return 0;
}
-static int postrm_upgrade_old_pkg_unwind(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)
{
/* DPKG_INCOMPATIBILITY:
dpkg does some things here that we don't do yet. Do we care?
@@ -1422,7 +923,8 @@ static int postrm_upgrade_old_pkg_unwind(opkg_conf_t *conf, pkg_t *pkg, pkg_t *o
return 0;
}
-static int remove_obsolesced_files(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)
{
int err;
str_list_t *old_files;
@@ -1481,7 +983,8 @@ static int remove_obsolesced_files(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg
return 0;
}
-static int install_maintainer_scripts(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)
{
int ret;
char *prefix;
@@ -1494,7 +997,8 @@ static int install_maintainer_scripts(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_
return ret;
}
-static int remove_disappeared(opkg_conf_t *conf, pkg_t *pkg)
+static int
+remove_disappeared(opkg_conf_t *conf, pkg_t *pkg)
{
/* DPKG_INCOMPATIBILITY:
This is a fairly sophisticated dpkg operation. Shall we
@@ -1514,7 +1018,8 @@ static int remove_disappeared(opkg_conf_t *conf, pkg_t *pkg)
return 0;
}
-static int install_data_files(opkg_conf_t *conf, pkg_t *pkg)
+static int
+install_data_files(opkg_conf_t *conf, pkg_t *pkg)
{
int err;
@@ -1563,7 +1068,56 @@ static int install_data_files(opkg_conf_t *conf, pkg_t *pkg)
return 0;
}
-static int resolve_conffiles(opkg_conf_t *conf, pkg_t *pkg)
+static int
+user_prefers_old_conffile(const char *file_name, const char *backup)
+{
+ char *response;
+ const char *short_file_name;
+
+ short_file_name = strrchr(file_name, '/');
+ if (short_file_name) {
+ short_file_name++;
+ } else {
+ short_file_name = file_name;
+ }
+
+ while (1) {
+ response = get_user_response(" Configuration file '%s'\n"
+ " ==> File on system created by you or by a script.\n"
+ " ==> File also in package provided by package maintainer.\n"
+ " What would you like to do about it ? Your options are:\n"
+ " Y or I : install the package maintainer's version\n"
+ " N or O : keep your currently-installed version\n"
+ " D : show the differences between the versions (if diff is installed)\n"
+ " The default action is to keep your current version.\n"
+ " *** %s (Y/I/N/O/D) [default=N] ? ", file_name, short_file_name);
+
+ if (response == NULL)
+ return 1;
+
+ if (strcmp(response, "y") == 0
+ || strcmp(response, "i") == 0
+ || strcmp(response, "yes") == 0) {
+ free(response);
+ return 0;
+ }
+
+ if (strcmp(response, "d") == 0) {
+ const char *argv[] = {"diff", "-u", backup, file_name, NULL};
+ xsystem(argv);
+ printf(" [Press ENTER to continue]\n");
+ response = file_read_line_alloc(stdin);
+ free(response);
+ continue;
+ }
+
+ free(response);
+ return 1;
+ }
+}
+
+static int
+resolve_conffiles(opkg_conf_t *conf, pkg_t *pkg)
{
conffile_list_elt_t *iter;
conffile_t *cf;
@@ -1613,102 +1167,387 @@ static int resolve_conffiles(opkg_conf_t *conf, pkg_t *pkg)
return 0;
}
-static int user_prefers_old_conffile(const char *file_name, const char *backup)
+
+opkg_error_t
+opkg_install_by_name(opkg_conf_t *conf, const char *pkg_name)
{
- char *response;
- const char *short_file_name;
+ int cmp, err = 0;
+ pkg_t *old, *new;
+ char *old_version, *new_version;
- short_file_name = strrchr(file_name, '/');
- if (short_file_name) {
- short_file_name++;
- } else {
- short_file_name = file_name;
- }
+ 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 );
- while (1) {
- response = get_user_response(" Configuration file '%s'\n"
- " ==> File on system created by you or by a script.\n"
- " ==> File also in package provided by package maintainer.\n"
- " What would you like to do about it ? Your options are:\n"
- " Y or I : install the package maintainer's version\n"
- " N or O : keep your currently-installed version\n"
- " D : show the differences between the versions (if diff is installed)\n"
- " The default action is to keep your current version.\n"
- " *** %s (Y/I/N/O/D) [default=N] ? ", file_name, short_file_name);
+/* 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 (response == NULL)
- return 1;
+ 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 (strcmp(response, "y") == 0
- || strcmp(response, "i") == 0
- || strcmp(response, "yes") == 0) {
- free(response);
+ 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 */
}
+ free(old_version);
+ free(new_version);
+ }
- if (strcmp(response, "d") == 0) {
- const char *argv[] = {"diff", "-u", backup, file_name, NULL};
- xsystem(argv);
- printf(" [Press ENTER to continue]\n");
- response = file_read_line_alloc(stdin);
- free(response);
- continue;
- }
+ /* 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. */
- free(response);
- return 1;
- }
+ opkg_message(conf, OPKG_DEBUG2,"Function: %s calling opkg_install_pkg \n",__FUNCTION__);
+ return opkg_install_pkg(conf, new,0);
}
-static char *backup_filename_alloc(const char *file_name)
+/**
+ * @brief Really install a pkg_t
+ */
+int
+opkg_install_pkg(opkg_conf_t *conf, pkg_t *pkg, int from_upgrade)
{
- char *backup;
+ int err = 0;
+ int message = 0;
+ pkg_t *old_pkg = NULL;
+ pkg_vec_t *replacees;
+ abstract_pkg_t *ab_pkg = NULL;
+ int old_state_flag;
+ char* file_md5;
+#ifdef HAVE_SHA256
+ char* file_sha256;
+#endif
- sprintf_alloc(&backup, "%s%s", file_name, OPKG_BACKUP_SUFFIX);
+ if ( from_upgrade )
+ message = 1; /* Coming from an upgrade, and should change the output message */
- return backup;
-}
+ if (!pkg) {
+ opkg_message(conf, OPKG_ERROR,
+ "INTERNAL ERROR: null pkg passed to opkg_install_pkg\n");
+ return OPKG_INSTALL_ERR_INTERNAL;
+ }
-int backup_make_backup(opkg_conf_t *conf, const char *file_name)
-{
- int err;
- char *backup;
+ opkg_message(conf, OPKG_DEBUG2, "Function: %s calling pkg_arch_supported %s \n", __FUNCTION__, __FUNCTION__);
+
+ if (!pkg_arch_supported(conf, pkg)) {
+ opkg_message(conf, OPKG_ERROR, "INTERNAL ERROR: architecture %s for pkg %s is unsupported.\n",
+ pkg->architecture, pkg->name);
+ return OPKG_INSTALL_ERR_INTERNAL;
+ }
+ if (pkg->state_status == SS_INSTALLED && conf->force_reinstall == 0 && conf->nodeps == 0) {
+ err = satisfy_dependencies_for(conf, pkg);
+ if (err) { return OPKG_INSTALL_ERR_DEPENDENCIES; }
+
+ opkg_message(conf, OPKG_NOTICE,
+ "Package %s is already installed in %s.\n",
+ pkg->name, pkg->dest->name);
+ return 0;
+ }
+
+ if (pkg->dest == NULL) {
+ pkg->dest = conf->default_dest;
+ }
+
+ old_pkg = pkg_hash_fetch_installed_by_name(&conf->pkg_hash, pkg->name);
+
+ err = opkg_install_check_downgrade(conf, pkg, old_pkg, message);
+ if (err) { return OPKG_INSTALL_ERR_NO_DOWNGRADE; }
+
+ pkg->state_want = SW_INSTALL;
+ if (old_pkg){
+ old_pkg->state_want = SW_DEINSTALL; /* needed for check_data_file_clashes of dependences */
+ }
+
+
+ /* Abhaya: conflicts check */
+ err = check_conflicts_for(conf, pkg);
+ if (err) { return OPKG_INSTALL_ERR_CONFLICTS; }
- backup = backup_filename_alloc(file_name);
- err = file_copy(file_name, backup);
- if (err) {
- opkg_message(conf, OPKG_ERROR,
- "%s: Failed to copy %s to %s\n",
- __FUNCTION__, file_name, backup);
+ /* this setup is to remove the upgrade scenario in the end when
+ installing pkg A, A deps B & B deps on A. So both B and A are
+ installed. Then A's installation is started resulting in an
+ uncecessary upgrade */
+ if (pkg->state_status == SS_INSTALLED
+ && conf->force_reinstall == 0) return 0;
+
+ err = verify_pkg_installable(conf, pkg);
+ if (err) { return OPKG_INSTALL_ERR_NO_SPACE; }
+
+ if (pkg->local_filename == NULL) {
+ err = opkg_download_pkg(conf, pkg, conf->tmp_dir);
+ if (err) {
+ opkg_message(conf, OPKG_ERROR,
+ "Failed to download %s. Perhaps you need to run 'opkg update'?\n",
+ pkg->name);
+ return OPKG_INSTALL_ERR_DOWNLOAD;
+ }
}
- free(backup);
+ /* check that the repository is valid */
+ #if defined(HAVE_GPGME) || defined(HAVE_OPENSSL)
+ char *list_file_name, *sig_file_name, *lists_dir;
- return err;
-}
+ /* check to ensure the package has come from a repository */
+ if (conf->check_signature && pkg->src)
+ {
+ sprintf_alloc (&lists_dir, "%s",
+ (conf->restrict_to_default_dest)
+ ? conf->default_dest->lists_dir
+ : conf->lists_dir);
+ sprintf_alloc (&list_file_name, "%s/%s", lists_dir, pkg->src->name);
+ sprintf_alloc (&sig_file_name, "%s/%s.sig", lists_dir, pkg->src->name);
-static int backup_exists_for(const char *file_name)
-{
- int ret;
- char *backup;
+ if (file_exists (sig_file_name))
+ {
+ if (opkg_verify_file (conf, list_file_name, sig_file_name)){
+ opkg_message(conf, OPKG_ERROR, "Failed to verify the signature of: %s\n",
+ list_file_name);
+ return OPKG_INSTALL_ERR_SIGNATURE;
+ }
+ }else{
+ opkg_message(conf, OPKG_ERROR, "Signature file is missing. "
+ "Perhaps you need to run 'opkg update'?\n");
+ return OPKG_INSTALL_ERR_SIGNATURE;
+ }
- backup = backup_filename_alloc(file_name);
+ free (lists_dir);
+ free (list_file_name);
+ free (sig_file_name);
+ }
+ #endif
- ret = file_exists(backup);
+ /* Check for md5 values */
+ if (pkg->md5sum)
+ {
+ file_md5 = file_md5sum_alloc(pkg->local_filename);
+ if (file_md5 && strcmp(file_md5, pkg->md5sum))
+ {
+ opkg_message(conf, OPKG_ERROR,
+ "Package %s md5sum mismatch. Either the opkg or the package index are corrupt. Try 'opkg update'.\n",
+ pkg->name);
+ free(file_md5);
+ return OPKG_INSTALL_ERR_MD5;
+ }
+ if (file_md5)
+ free(file_md5);
+ }
- free(backup);
+#ifdef HAVE_SHA256
+ /* Check for sha256 value */
+ if(pkg->sha256sum)
+ {
+ file_sha256 = file_sha256sum_alloc(pkg->local_filename);
+ if (file_sha256 && strcmp(file_sha256, pkg->sha256sum))
+ {
+ opkg_message(conf, OPKG_ERROR,
+ "Package %s sha256sum mismatch. Either the opkg or the package index are corrupt. Try 'opkg update'.\n",
+ pkg->name);
+ free(file_sha256);
+ return OPKG_INSTALL_ERR_SHA256;
+ }
+ if (file_sha256)
+ free(file_sha256);
+ }
+#endif
- return ret;
-}
+ if (pkg->tmp_unpack_dir == NULL) {
+ unpack_pkg_control_files(conf, pkg);
+ }
-static int backup_remove(const char *file_name)
-{
- char *backup;
+ /* We should update the filelist here, so that upgrades of packages that split will not fail. -Jamey 27-MAR-03 */
+/* Pigi: check if it will pass from here when replacing. It seems to fail */
+/* That's rather strange that files don't change owner. Investigate !!!!!!*/
+ err = update_file_ownership(conf, pkg, old_pkg);
+ if (err) { return OPKG_ERR_UNKNOWN; }
- backup = backup_filename_alloc(file_name);
- unlink(backup);
- free(backup);
+ if (conf->nodeps == 0) {
+ err = satisfy_dependencies_for(conf, pkg);
+ if (err) { return OPKG_INSTALL_ERR_DEPENDENCIES; }
+ if (pkg->state_status == SS_UNPACKED)
+ /* Circular dependency has installed it for us. */
+ return 0;
+ }
+
+ replacees = pkg_vec_alloc();
+ pkg_get_installed_replacees(conf, pkg, replacees);
+
+ /* this next section we do with SIGINT blocked to prevent inconsistency between opkg database and filesystem */
+ {
+ sigset_t newset, oldset;
+
+ sigemptyset(&newset);
+ sigaddset(&newset, SIGINT);
+ sigprocmask(SIG_BLOCK, &newset, &oldset);
+
+ opkg_state_changed++;
+ pkg->state_flag |= SF_FILELIST_CHANGED;
+
+ if (old_pkg)
+ pkg_remove_orphan_dependent(conf, pkg, old_pkg);
+
+ /* XXX: BUG: we really should treat replacement more like an upgrade
+ * Instead, we're going to remove the replacees
+ */
+ err = pkg_remove_installed_replacees(conf, replacees);
+ if (err) goto UNWIND_REMOVE_INSTALLED_REPLACEES;
+
+ err = prerm_upgrade_old_pkg(conf, pkg, old_pkg);
+ if (err) goto UNWIND_PRERM_UPGRADE_OLD_PKG;
+
+ err = prerm_deconfigure_conflictors(conf, pkg, replacees);
+ if (err) goto UNWIND_PRERM_DECONFIGURE_CONFLICTORS;
+
+ err = preinst_configure(conf, pkg, old_pkg);
+ if (err) goto UNWIND_PREINST_CONFIGURE;
+
+ err = backup_modified_conffiles(conf, pkg, old_pkg);
+ if (err) goto UNWIND_BACKUP_MODIFIED_CONFFILES;
+
+ err = check_data_file_clashes(conf, pkg, old_pkg);
+ if (err) goto UNWIND_CHECK_DATA_FILE_CLASHES;
+
+ err = postrm_upgrade_old_pkg(conf, pkg, old_pkg);
+ if (err) goto UNWIND_POSTRM_UPGRADE_OLD_PKG;
+
+ if (conf->noaction) return 0;
+
+ /* point of no return: no unwinding after this */
+ if (old_pkg && !conf->force_reinstall) {
+ old_pkg->state_want = SW_DEINSTALL;
+
+ if (old_pkg->state_flag & SF_NOPRUNE) {
+ opkg_message(conf, OPKG_INFO,
+ " not removing obsolesced files because package marked noprune\n");
+ } else {
+ opkg_message(conf, OPKG_INFO,
+ " removing obsolesced files\n");
+ remove_obsolesced_files(conf, pkg, old_pkg);
+ }
+ /* removing files from old package, to avoid ghost files */
+ remove_data_files_and_list(conf, old_pkg);
+/* Pigi : It should be better to remove also maintainer and postrem scripts here, just in case*/
+ remove_maintainer_scripts_except_postrm(conf, old_pkg);
+ remove_postrm(conf, old_pkg);
+/* Pigi */
+
+ }
- return 0;
-}
+ opkg_message(conf, OPKG_INFO,
+ " installing maintainer scripts\n");
+ install_maintainer_scripts(conf, pkg, old_pkg);
+
+ /* the following just returns 0 */
+ remove_disappeared(conf, pkg);
+
+ opkg_message(conf, OPKG_INFO,
+ " installing data files\n");
+ install_data_files(conf, pkg);
+
+/* read comments from function for detail but I will execute this here as all other tests are ok.*/
+ err = check_data_file_clashes_change(conf, pkg, old_pkg);
+
+ opkg_message(conf, OPKG_INFO,
+ " resolving conf files\n");
+ resolve_conffiles(conf, pkg);
+
+ pkg->state_status = SS_UNPACKED;
+ old_state_flag = pkg->state_flag;
+ pkg->state_flag &= ~SF_PREFER;
+ opkg_message(conf, OPKG_DEBUG, " pkg=%s old_state_flag=%x state_flag=%x\n", pkg->name, old_state_flag, pkg->state_flag);
+
+ if (old_pkg && !conf->force_reinstall) {
+ old_pkg->state_status = SS_NOT_INSTALLED;
+ }
+
+ time(&pkg->installed_time);
+
+ ab_pkg = pkg->parent;
+ if (ab_pkg)
+ ab_pkg->state_status = pkg->state_status;
+
+ opkg_message(conf, OPKG_INFO, "Done.\n");
+
+ sigprocmask(SIG_UNBLOCK, &newset, &oldset);
+ pkg_vec_free (replacees);
+ return 0;
+
+
+ UNWIND_POSTRM_UPGRADE_OLD_PKG:
+ postrm_upgrade_old_pkg_unwind(conf, pkg, old_pkg);
+ UNWIND_CHECK_DATA_FILE_CLASHES:
+ check_data_file_clashes_unwind(conf, pkg, old_pkg);
+ UNWIND_BACKUP_MODIFIED_CONFFILES:
+ backup_modified_conffiles_unwind(conf, pkg, old_pkg);
+ UNWIND_PREINST_CONFIGURE:
+ preinst_configure_unwind(conf, pkg, old_pkg);
+ UNWIND_PRERM_DECONFIGURE_CONFLICTORS:
+ prerm_deconfigure_conflictors_unwind(conf, pkg, replacees);
+ UNWIND_PRERM_UPGRADE_OLD_PKG:
+ prerm_upgrade_old_pkg_unwind(conf, pkg, old_pkg);
+ UNWIND_REMOVE_INSTALLED_REPLACEES:
+ pkg_remove_installed_replacees_unwind(conf, replacees);
+
+ opkg_message(conf, OPKG_INFO,
+ "Failed.\n");
+
+ sigprocmask(SIG_UNBLOCK, &newset, &oldset);
+
+ pkg_vec_free (replacees);
+ return OPKG_ERR_UNKNOWN;
+ }
+}
diff --git a/libopkg/opkg_install.h b/libopkg/opkg_install.h
index 4bed953..d6d074f 100644
--- a/libopkg/opkg_install.h
+++ b/libopkg/opkg_install.h
@@ -23,14 +23,6 @@
#include "opkg_error.h"
opkg_error_t opkg_install_by_name(opkg_conf_t *conf, const char *pkg_name);
-opkg_error_t opkg_install_multi_by_name(opkg_conf_t *conf, const char *pkg_name);
-int opkg_install_from_file(opkg_conf_t *conf, const char *filename);
-int opkg_install_pkg(opkg_conf_t *conf, pkg_t *pkg,int from_upgrading);
-int satisfy_dependencies_for(opkg_conf_t *conf, pkg_t *pkg);
-
-int opkg_satisfy_all_dependences(opkg_conf_t *conf);
-
-int pkg_mark_dependencies_for_installation(opkg_conf_t *conf, pkg_t *pkg_name, pkg_vec_t *pkgs_needed);
-int name_mark_dependencies_for_installation(opkg_conf_t *conf, const char *pkg_name, pkg_vec_t *pkgs_needed);
+int opkg_install_pkg(opkg_conf_t *conf, pkg_t *pkg, int from_upgrading);
#endif