- 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;
- char *pkgid;
-
- 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 HAVE_GPGME
- 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))
- 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 (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;
- }
- free(file_md5);
- }
-
- 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; }
- }
-
- replacees = pkg_vec_alloc();
- pkg_get_installed_replacees(conf, pkg, replacees);
-
- sprintf_alloc (&pkgid, "%s;%s;%s;", pkg->name, pkg->version, pkg->architecture);
- opkg_set_current_state (conf, OPKG_STATE_INSTALLING_PKG, pkgid);
- free (pkgid);
-
- /* this next section we do with SIGINT blocked to prevent inconsistency between opkg database and filesystem */
- {
- sigset_t newset, oldset;
- sighandler_t old_handler = NULL;
- int use_signal = 0;
- caught_sigint = 0;
- if (use_signal) {
- old_handler = signal(SIGINT, opkg_install_pkg_sigint_handler);
- } else {
- sigemptyset(&newset);
- sigaddset(&newset, SIGINT);
- sigprocmask(SIG_BLOCK, &newset, &oldset);
- }
-
- opkg_state_changed++;
- pkg->state_flag |= SF_FILELIST_CHANGED;
-
- 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);
-
- opkg_message(conf, OPKG_INFO,
- " cleanup temp files\n");
- cleanup_temporary_files(conf, pkg);
-
- ab_pkg = pkg->parent;
- if (ab_pkg)
- ab_pkg->state_status = pkg->state_status;
-
- opkg_message(conf, OPKG_INFO, "Done.\n");
-
- if (use_signal)
- signal(SIGINT, old_handler);
- else
- 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,
- " cleanup temp files\n");
- cleanup_temporary_files(conf, pkg);
-
- opkg_message(conf, OPKG_INFO,
- "Failed.\n");
- if (use_signal)
- signal(SIGINT, old_handler);
- else
- sigprocmask(SIG_UNBLOCK, &newset, &oldset);
-
- pkg_vec_free (replacees);
- return OPKG_ERR_UNKNOWN;
- }
- opkg_set_current_state (conf, OPKG_STATE_NONE, NULL);
+ if (old_pkg) {
+ char message_out[15];
+ char *old_version = pkg_version_str_alloc(old_pkg);
+ char *new_version = pkg_version_str_alloc(pkg);
+ int cmp = pkg_compare_versions(old_pkg, pkg);
+ int rc = 0;
+
+ memset(message_out, '\x0', 15);
+ strncpy(message_out, "Upgrading ", strlen("Upgrading "));
+ 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 */
+ strncpy(message_out, "Downgrading ", strlen("Downgrading ")); /* 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) {
+ if (!conf->download_only)
+ opkg_msg(NOTICE,
+ "Not downgrading package %s on %s from %s to %s.\n",
+ old_pkg->name, old_pkg->dest->name,
+ old_version, new_version);
+ rc = 1;
+ } else if (cmp < 0) {
+ if (!conf->download_only)
+ opkg_msg(NOTICE,
+ "%s%s on %s from %s to %s...\n",
+ message_out, pkg->name,
+ old_pkg->dest->name, old_version,
+ new_version);
+ pkg->dest = old_pkg->dest;
+ rc = 0;
+ } else { /* cmp == 0 */
+
+ if (!conf->download_only)
+ opkg_msg(NOTICE,
+ "%s (%s) already install on %s.\n",
+ pkg->name, new_version,
+ old_pkg->dest->name);
+ rc = 1;
+ }
+ free(old_version);
+ free(new_version);
+ return rc;
+ } else {
+ char message_out[15];
+ memset(message_out, '\x0', 15);
+ if (message)
+ strncpy(message_out, "Upgrading ",
+ strlen("Upgrading "));
+ else
+ strncpy(message_out, "Installing ",
+ strlen("Installing "));
+ char *version = pkg_version_str_alloc(pkg);
+
+ if (!conf->download_only)
+ opkg_msg(NOTICE, "%s%s (%s) to %s...\n", message_out,
+ pkg->name, version, pkg->dest->name);
+ free(version);
+ }
+ return 0;