#include <time.h>
#include <signal.h>
#include <unistd.h>
+#include <sys/stat.h>
#include "pkg.h"
#include "pkg_hash.h"
char **tmp, **unresolved = NULL;
int ndepends;
- ndepends = pkg_hash_fetch_unsatisfied_dependencies(pkg, depends,
+ ndepends = pkg_hash_fetch_unsatisfied_dependencies(pkg, depends,
&unresolved);
if (unresolved) {
i = 0;
while (i < conflicts->len)
opkg_msg(level, "\t%s", conflicts->pkgs[i++]->name);
- opkg_msg(level, "\n");
+ opkg_message(level, "\n");
pkg_vec_free(conflicts);
return -1;
}
if (new_list == NULL)
return -1;
- for (iter = str_list_first(new_list), niter = str_list_next(new_list, iter);
- iter;
+ for (iter = str_list_first(new_list), niter = str_list_next(new_list, iter);
+ iter;
iter = niter, niter = str_list_next(new_list, niter)) {
char *new_file = (char *)iter->data;
pkg_t *owner = file_hash_get_file_owner(new_file);
- if (!new_file)
- opkg_msg(ERROR, "Null new_file for new_pkg=%s\n", new_pkg->name);
- if (!owner || (owner == old_pkg))
+ pkg_t *obs = hash_table_get(&conf->obs_file_hash, new_file);
+
+ opkg_msg(DEBUG2, "%s: new_pkg=%s wants file %s, from owner=%s\n",
+ __func__, new_pkg->name, new_file, owner?owner->name:"<NULL>");
+
+ if (!owner || (owner == old_pkg) || obs)
file_hash_set_file_owner(new_file, new_pkg);
}
return -1;
}
- for (iter = str_list_first(old_list), niter = str_list_next(old_list, iter);
- iter;
+ for (iter = str_list_first(old_list), niter = str_list_next(old_list, iter);
+ iter;
iter = niter, niter = str_list_next(old_list, niter)) {
char *old_file = (char *)iter->data;
pkg_t *owner = file_hash_get_file_owner(old_file);
- if (owner == old_pkg) {
+ if (!owner || (owner == old_pkg)) {
/* obsolete */
hash_table_insert(&conf->obs_file_hash, old_file, old_pkg);
}
verify_pkg_installable(pkg_t *pkg)
{
unsigned long kbs_available, pkg_size_kbs;
- char *root_dir;
+ char *root_dir = NULL;
+ struct stat s;
if (conf->force_space || pkg->installed_size == 0)
return 0;
- root_dir = pkg->dest ? pkg->dest->root_dir :
- conf->default_dest->root_dir;
+ if (pkg->dest)
+ {
+ if (!strcmp(pkg->dest->name, "root") && conf->overlay_root
+ && !stat(conf->overlay_root, &s) && (s.st_mode & S_IFDIR))
+ root_dir = conf->overlay_root;
+ else
+ root_dir = pkg->dest->root_dir;
+ }
+
+ if (!root_dir)
+ root_dir = conf->default_dest->root_dir;
+
kbs_available = get_available_kbytes(root_dir);
pkg_size_kbs = (pkg->installed_size + 1023)/1024;
if (pkg_size_kbs >= kbs_available) {
- opkg_msg(ERROR, "Only have %dkb available on filesystem %s, "
- "pkg %s needs %d\n",
+ opkg_msg(ERROR, "Only have %ldkb available on filesystem %s, "
+ "pkg %s needs %ld\n",
kbs_available, root_dir, pkg->name, pkg_size_kbs);
return -1;
}
free(conffiles_file_name);
return 0;
}
-
+
conffiles_file = fopen(conffiles_file_name, "r");
if (conffiles_file == NULL) {
opkg_perror(ERROR, "Failed to open %s", conffiles_file_name);
while (1) {
char *cf_name;
char *cf_name_in_dest;
+ int i;
cf_name = file_read_line_alloc(conffiles_file);
if (cf_name == NULL) {
if (cf_name[0] == '\0') {
continue;
}
+ for (i = strlen(cf_name) - 1;
+ (i >= 0) && (cf_name[i] == ' ' || cf_name[i] == '\t');
+ i--
+ ) {
+ cf_name[i] = '\0';
+ }
/* Prepend dest->root_dir to conffile name.
Take pains to avoid multiple slashes. */
* which are no longer a dependency in the new (upgraded) pkg.
*/
static int
-pkg_remove_orphan_dependent(pkg_t *pkg, pkg_t *old_pkg)
+pkg_remove_orphan_dependent(pkg_t *pkg, pkg_t *old_pkg)
{
int i, j, k, l, found,r, err = 0;
int n_deps;
found = 0;
for (k=0; k<count1; k++) {
- cd1 = &pkg->depends[i];
+ cd1 = &pkg->depends[k];
if (cd1->type != DEPEND)
continue;
for (l=0; l<cd1->possibility_count; l++) {
r = opkg_remove_pkg(p, 0);
if (!err)
err = r;
- } else
+ } else
opkg_msg(INFO, "%s was autoinstalled and is "
"still required by %d "
"installed packages.\n",
/* 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(pkg_t *pkg, pkg_t *old_pkg, int message)
-{
+{
if (old_pkg) {
char message_out[15];
char *old_version = pkg_version_str_alloc(old_pkg);
int rc = 0;
memset(message_out,'\x0',15);
- strncpy (message_out,"Upgrading ",strlen("Upgrading "));
+ 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 */
+ 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)
pkg->dest = old_pkg->dest;
rc = 0;
} else /* cmp == 0 */ {
- if (conf->force_reinstall) {
if(!conf->download_only)
- opkg_msg(NOTICE, "Reinstalling %s (%s) on %s...\n",
- pkg->name, new_version, old_pkg->dest->name);
- pkg->dest = old_pkg->dest;
- rc = 0;
- } else {
- if(!conf->download_only)
- opkg_msg(NOTICE, "%s (%s) already install on %s."
- " Not reinstalling.\n",
- pkg->name, new_version, old_pkg->dest->name);
- rc = 1;
- }
- }
+ 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 )
+ if ( message )
strncpy( message_out,"Upgrading ",strlen("Upgrading ") );
else
strncpy( message_out,"Installing ",strlen("Installing ") );
{
/* DPKG_INCOMPATIBILITY:
dpkg does some things here that we don't do yet. Do we care?
-
+
1. If a version of the package is already installed, call
old-prerm upgrade new-version
2. If the script runs but exits with a non-zero exit status
{
int err;
char *backup;
-
+
backup = backup_filename_alloc(file_name);
err = file_copy(file_name, backup);
if (err) {
if (old_pkg) {
for (iter = nv_pair_list_first(&old_pkg->conffiles); iter; iter = nv_pair_list_next(&old_pkg->conffiles, iter)) {
char *cf_name;
-
+
cf = iter->data;
cf_name = root_filename_alloc(cf->name);
can unwind if necessary). To avoid complexity and redundant
storage, opkg doesn't do any installation until later, (at the
point at which dpkg removes the backups.
-
+
But, we do have to check for data file clashes, since after
installing a package with a file clash, removing either of the
packages involved in the clash has the potential to break the
if (files_list == NULL)
return -1;
- for (iter = str_list_first(files_list), niter = str_list_next(files_list, iter);
- iter;
+ for (iter = str_list_first(files_list), niter = str_list_next(files_list, iter);
+ iter;
iter = niter, niter = str_list_next(files_list, iter)) {
filename = (char *) iter->data;
if (file_exists(filename) && (! file_is_dir(filename))) {
continue;
}
- /* Pre-existing files are OK if force-overwrite was asserted. */
+ /* Pre-existing files are OK if force-overwrite was asserted. */
if (conf->force_overwrite) {
/* but we need to change who owns this file */
file_hash_set_file_owner(filename, pkg);
if (files_list == NULL)
return -1;
- for (iter = str_list_first(files_list), niter = str_list_next(files_list, iter);
- iter;
+ for (iter = str_list_first(files_list), niter = str_list_next(files_list, iter);
+ iter;
iter = niter, niter = str_list_next(files_list, niter)) {
char *filename = (char *) iter->data;
if (root_filename) {
/* Pre-existing files are OK if owned by a package replaced by new pkg. */
if (owner) {
if (pkg_replaces(pkg, owner)) {
-/* It's now time to change the owner of that file.
+/* It's now time to change the owner of that file.
It has been "replaced" from the new "Replaces", then I need to inform lists file about that. */
opkg_msg(INFO, "Replacing pre-existing file %s "
"owned by package %s\n",
/* in case obsolete file no longer belongs to old_pkg */
continue;
}
-
+
/* old file is obsolete */
- opkg_msg(INFO, "Removing obsolete file %s.\n", old);
+ opkg_msg(NOTICE, "Removing obsolete file %s.\n", old);
if (!conf->noaction) {
err = unlink(old);
if (err) {
/* DPKG_INCOMPATIBILITY:
This is a fairly sophisticated dpkg operation. Shall we
skip it? */
-
+
/* Any packages all of whose files have been overwritten during the
installation, and which aren't required for dependencies, are
considered to have been removed. For each such package
than dpkg. Rather than removing backups at this point, we
actually do the data file installation now. See comments in
check_data_file_clashes() for more details. */
-
+
opkg_msg(INFO, "Extracting data files to %s.\n", pkg->dest->root_dir);
err = pkg_extract_data_files_to_dir(pkg, pkg->dest->root_dir);
if (err) {
* XXX: This should be fixed outside of opkg, in the Package list.
*/
set_flags_from_control(pkg) ;
-
+
opkg_msg(DEBUG, "Calling pkg_write_filelist.\n");
err = pkg_write_filelist(pkg);
if (err)
if (old)
opkg_msg(DEBUG2, "Old versions from pkg_hash_fetch %s.\n",
old->version);
-
+
new = pkg_hash_fetch_best_installation_candidate_by_name(pkg_name);
if (new == NULL) {
opkg_msg(NOTICE, "Unknown package '%s'.\n", pkg_name);
}
opkg_msg(DEBUG2, "Versions from pkg_hash_fetch:");
- if ( old )
- opkg_msg(DEBUG2, " old %s ", old->version);
- opkg_msg(DEBUG2, " new %s\n", new->version);
+ if ( old )
+ opkg_message(DEBUG2, " old %s ", old->version);
+ opkg_message(DEBUG2, " new %s\n", new->version);
new->state_flag |= SF_USER;
if (old) {
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_msg(DEBUG, "Forcing downgrade\n");
- cmp = -1 ; /* then we force opkg to 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_msg(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) {
+ if (cmp == 0) {
opkg_msg(NOTICE,
"Package %s (%s) installed in %s is up to date.\n",
old->name, old_version, old->dest->name);
return 0;
} else if (cmp < 0) {
new->dest = old->dest;
- old->state_want = SW_DEINSTALL; /* Here probably the problem for bug 1277 */
+ old->state_want = SW_DEINSTALL;
}
free(old_version);
free(new_version);
}
/**
- * @brief Really install a pkg_t
+ * @brief Really install a pkg_t
*/
int
opkg_install_pkg(pkg_t *pkg, int from_upgrade)
#endif
sigset_t newset, oldset;
- if ( from_upgrade )
+ if ( from_upgrade )
message = 1; /* Coming from an upgrade, and should change the output message */
opkg_msg(DEBUG2, "Calling pkg_arch_supported.\n");
pkg->architecture, pkg->name);
return -1;
}
- if (pkg->state_status == SS_INSTALLED && conf->force_reinstall == 0 && conf->nodeps == 0) {
+ if (pkg->state_status == SS_INSTALLED && conf->nodeps == 0) {
err = satisfy_dependencies_for(pkg);
if (err)
return -1;
- opkg_msg(NOTICE, "Package %s is already installed on %s.\n",
+ opkg_msg(NOTICE, "Package %s is already installed on %s.\n",
pkg->name, pkg->dest->name);
return 0;
}
return -1;
pkg->state_want = SW_INSTALL;
- if (old_pkg){
+ if (old_pkg){
old_pkg->state_want = SW_DEINSTALL; /* needed for check_data_file_clashes of dependencies */
}
err = check_conflicts_for(pkg);
if (err)
return -1;
-
+
/* 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)
+ uncecessary upgrade */
+ if (pkg->state_status == SS_INSTALLED)
return 0;
-
+
err = verify_pkg_installable(pkg);
if (err)
return -1;
file_md5 = file_md5sum_alloc(pkg->local_filename);
if (file_md5 && strcmp(file_md5, pkg->md5sum))
{
- opkg_msg(ERROR, "Package %s md5sum mismatch. "
- "Either the opkg or the package index are corrupt. "
- "Try 'opkg update'.\n",
- pkg->name);
- free(file_md5);
- return -1;
+ if (!conf->force_checksum)
+ {
+ opkg_msg(ERROR, "Package %s md5sum mismatch. "
+ "Either the opkg or the package index are corrupt. "
+ "Try 'opkg update'.\n",
+ pkg->name);
+ free(file_md5);
+ return -1;
+ }
+ else
+ {
+ opkg_msg(NOTICE, "Ignored %s md5sum mismatch.\n", pkg->name);
+ }
}
if (file_md5)
free(file_md5);
pkg_remove_orphan_dependent(pkg, old_pkg);
/* XXX: BUG: we really should treat replacement more like an upgrade
- * Instead, we're going to remove the replacees
+ * Instead, we're going to remove the replacees
*/
err = pkg_remove_installed_replacees(replacees);
if (err)
return 0;
/* point of no return: no unwinding after this */
- if (old_pkg && !conf->force_reinstall) {
+ if (old_pkg) {
old_pkg->state_want = SW_DEINSTALL;
if (old_pkg->state_flag & SF_NOPRUNE) {
}
}
- /* removing files from old package, to avoid ghost files */
+ /* removing files from old package, to avoid ghost files */
remove_data_files_and_list(old_pkg);
remove_maintainer_scripts(old_pkg);
}
opkg_msg(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) {
+ if (old_pkg)
old_pkg->state_status = SS_NOT_INSTALLED;
- }
time(&pkg->installed_time);
sigprocmask(SIG_UNBLOCK, &newset, &oldset);
pkg_vec_free (replacees);
return 0;
-
+
UNWIND_POSTRM_UPGRADE_OLD_PKG:
postrm_upgrade_old_pkg_unwind(pkg, old_pkg);