X-Git-Url: https://git.librecmc.org/?p=oweals%2Fopkg-lede.git;a=blobdiff_plain;f=libopkg%2Fopkg_install.c;h=2c61a5fccd7b12f8d1598098030aaa702cf1b792;hp=94d61884125507ebdb464cf4235884b07e7931f2;hb=a2afaf0b997f88422e07f622ba2bec3f5786e4de;hpb=2fdb3fc0b67757afd6fe7a244b6e14d2a546af0e diff --git a/libopkg/opkg_install.c b/libopkg/opkg_install.c index 94d6188..2c61a5f 100644 --- a/libopkg/opkg_install.c +++ b/libopkg/opkg_install.c @@ -15,12 +15,13 @@ General Public License for more details. */ -#include "includes.h" -#include -#include -#include +#include "config.h" + +#include #include #include +#include +#include #include "pkg.h" #include "pkg_hash.h" @@ -50,7 +51,7 @@ satisfy_dependencies_for(pkg_t *pkg) 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) { @@ -58,12 +59,12 @@ satisfy_dependencies_for(pkg_t *pkg) pkg->name); tmp = unresolved; while (*unresolved) { - opkg_msg(ERROR, "\t%s", *unresolved); + opkg_message(ERROR, "\t%s", *unresolved); free(*unresolved); unresolved++; } free(tmp); - opkg_msg(ERROR, "\n"); + opkg_message(ERROR, "\n"); if (! conf->force_depends) { opkg_msg(INFO, "This could mean that your package list is out of date or that the packages\n" @@ -134,7 +135,7 @@ check_conflicts_for(pkg_t *pkg) 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; } @@ -151,14 +152,17 @@ update_file_ownership(pkg_t *new_pkg, pkg_t *old_pkg) 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:""); + + if (!owner || (owner == old_pkg) || obs) file_hash_set_file_owner(new_file, new_pkg); } @@ -169,12 +173,12 @@ update_file_ownership(pkg_t *new_pkg, pkg_t *old_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); } @@ -189,20 +193,31 @@ static int 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; } @@ -247,7 +262,7 @@ unpack_pkg_control_files(pkg_t *pkg) 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); @@ -259,6 +274,7 @@ unpack_pkg_control_files(pkg_t *pkg) while (1) { char *cf_name; char *cf_name_in_dest; + int i; cf_name = file_read_line_alloc(conffiles_file); if (cf_name == NULL) { @@ -267,6 +283,12 @@ unpack_pkg_control_files(pkg_t *pkg) 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. */ @@ -295,9 +317,9 @@ unpack_pkg_control_files(pkg_t *pkg) * 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; + int i, j, k, l, found,r, err = 0; int n_deps; pkg_t *p; struct compound_depend *cd0, *cd1; @@ -321,7 +343,7 @@ pkg_remove_orphan_dependent(pkg_t *pkg, pkg_t *old_pkg) found = 0; for (k=0; kdepends[i]; + cd1 = &pkg->depends[k]; if (cd1->type != DEPEND) continue; for (l=0; lpossibility_count; l++) { @@ -362,8 +384,10 @@ pkg_remove_orphan_dependent(pkg_t *pkg, pkg_t *old_pkg) * which we need to ignore during removal. */ p->state_flag |= SF_REPLACE; - opkg_remove_pkg(p, 0); - } else + r = opkg_remove_pkg(p, 0); + if (!err) + err = r; + } else opkg_msg(INFO, "%s was autoinstalled and is " "still required by %d " "installed packages.\n", @@ -372,7 +396,7 @@ pkg_remove_orphan_dependent(pkg_t *pkg, pkg_t *old_pkg) } } - return 0; + return err; } /* returns number of installed replacees */ @@ -436,7 +460,7 @@ pkg_remove_installed_replacees_unwind(pkg_vec_t *replacees) /* 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); @@ -445,53 +469,49 @@ opkg_install_check_downgrade(pkg_t *pkg, pkg_t *old_pkg, int message) 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) { - 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); + 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) { - opkg_msg(NOTICE, "%s%s on %s from %s to %s...\n", - message_out, pkg->name, old_pkg->dest->name, old_version, new_version); + 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->force_reinstall) { - 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 { - opkg_msg(NOTICE, "%s (%s) already install on %s." - " Not reinstalling.\n", - pkg->name, new_version, old_pkg->dest->name); - rc = 1; - } - } + 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); - - opkg_msg(NOTICE, "%s%s (%s) to %s...\n", message_out, - pkg->name, version, pkg->dest->name); - free(version); - return 0; + 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; } @@ -500,7 +520,7 @@ prerm_upgrade_old_pkg(pkg_t *pkg, pkg_t *old_pkg) { /* 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 @@ -614,7 +634,7 @@ backup_make_backup(const char *file_name) { int err; char *backup; - + backup = backup_filename_alloc(file_name); err = file_copy(file_name, backup); if (err) { @@ -667,7 +687,7 @@ backup_modified_conffiles(pkg_t *pkg, pkg_t *old_pkg) 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); @@ -733,7 +753,7 @@ check_data_file_clashes(pkg_t *pkg, pkg_t *old_pkg) 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 @@ -741,28 +761,26 @@ check_data_file_clashes(pkg_t *pkg, pkg_t *old_pkg) */ str_list_t *files_list; str_list_elt_t *iter, *niter; - + char *filename; int clashes = 0; files_list = pkg_get_installed_files(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, iter)) { - char *root_filename; - char *filename = (char *) iter->data; - root_filename = root_filename_alloc(filename); - if (file_exists(root_filename) && (! file_is_dir(root_filename))) { + filename = (char *) iter->data; + if (file_exists(filename) && (! file_is_dir(filename))) { pkg_t *owner; pkg_t *obs; - if (backup_exists_for(root_filename)) { + if (backup_exists_for(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); @@ -809,14 +827,13 @@ check_data_file_clashes(pkg_t *pkg, pkg_t *old_pkg) "\tBut that file is already provided by package ", pkg->name, filename); if (owner) { - opkg_msg(ERROR, "%s\n", owner->name); + opkg_message(ERROR, "%s\n", owner->name); } else { - opkg_msg(ERROR, "\n" + opkg_message(ERROR, "\n" "Please move this file out of the way and try again.\n"); } clashes++; } - free(root_filename); } pkg_free_installed_files(pkg); @@ -846,8 +863,8 @@ check_data_file_clashes_change(pkg_t *pkg, pkg_t *old_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) { @@ -870,7 +887,7 @@ check_data_file_clashes_change(pkg_t *pkg, pkg_t *old_pkg) /* 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", @@ -924,7 +941,7 @@ postrm_upgrade_old_pkg_unwind(pkg_t *pkg, pkg_t *old_pkg) static int remove_obsolesced_files(pkg_t *pkg, pkg_t *old_pkg) { - int err; + int err = 0; str_list_t *old_files; str_list_elt_t *of; str_list_t *new_files; @@ -964,9 +981,9 @@ remove_obsolesced_files(pkg_t *pkg, pkg_t *old_pkg) /* 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) { @@ -979,7 +996,7 @@ remove_obsolesced_files(pkg_t *pkg, pkg_t *old_pkg) pkg_free_installed_files(old_pkg); pkg_free_installed_files(pkg); - return 0; + return err; } static int @@ -1002,7 +1019,7 @@ remove_disappeared(pkg_t *pkg) /* 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 @@ -1026,7 +1043,7 @@ install_data_files(pkg_t *pkg) 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) { @@ -1039,7 +1056,7 @@ install_data_files(pkg_t *pkg) * 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) @@ -1096,7 +1113,7 @@ resolve_conffiles(pkg_t *pkg) } else { char *new_conffile; sprintf_alloc(&new_conffile, "%s-opkg", root_filename); - opkg_msg(NOTICE, "Existing conffile %s " + opkg_msg(ERROR, "Existing conffile %s " "is different from the conffile in the new package." " The new conffile will be placed at %s.\n", root_filename, new_conffile); @@ -1129,15 +1146,17 @@ opkg_install_by_name(const char *pkg_name) 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) + if (new == NULL) { + opkg_msg(NOTICE, "Unknown package '%s'.\n", pkg_name); return -1; + } 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) { @@ -1147,16 +1166,16 @@ opkg_install_by_name(const char *pkg_name) 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); @@ -1172,7 +1191,7 @@ opkg_install_by_name(const char *pkg_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); @@ -1183,7 +1202,7 @@ opkg_install_by_name(const char *pkg_name) } /** - * @brief Really install a pkg_t + * @brief Really install a pkg_t */ int opkg_install_pkg(pkg_t *pkg, int from_upgrade) @@ -1200,7 +1219,7 @@ 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"); @@ -1210,12 +1229,12 @@ opkg_install_pkg(pkg_t *pkg, int from_upgrade) 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; } @@ -1231,27 +1250,35 @@ opkg_install_pkg(pkg_t *pkg, int from_upgrade) return -1; pkg->state_want = SW_INSTALL; - if (old_pkg){ - old_pkg->state_want = SW_DEINSTALL; /* needed for check_data_file_clashes of dependences */ + 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; if (pkg->local_filename == NULL) { - err = opkg_download_pkg(pkg, conf->tmp_dir); + if(!conf->cache && conf->download_only){ + char cwd[4096]; + if(getcwd(cwd, sizeof(cwd)) != NULL) + err = opkg_download_pkg(pkg, cwd); + else + return -1; + } else { + err = opkg_download_pkg(pkg, conf->tmp_dir); + } if (err) { opkg_msg(ERROR, "Failed to download %s. " "Perhaps you need to run 'opkg update'?\n", @@ -1300,12 +1327,19 @@ opkg_install_pkg(pkg_t *pkg, int from_upgrade) 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); @@ -1329,6 +1363,14 @@ opkg_install_pkg(pkg_t *pkg, int from_upgrade) free(file_sha256); } #endif + if(conf->download_only) { + if (conf->nodeps == 0) { + err = satisfy_dependencies_for(pkg); + if (err) + return -1; + } + return 0; + } if (pkg->tmp_unpack_dir == NULL) { if (unpack_pkg_control_files(pkg) == -1) { @@ -1367,7 +1409,7 @@ opkg_install_pkg(pkg_t *pkg, int from_upgrade) 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) @@ -1401,7 +1443,7 @@ opkg_install_pkg(pkg_t *pkg, int from_upgrade) 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) { @@ -1418,7 +1460,7 @@ opkg_install_pkg(pkg_t *pkg, int from_upgrade) } } - /* 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); } @@ -1460,9 +1502,8 @@ opkg_install_pkg(pkg_t *pkg, int from_upgrade) 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); @@ -1473,7 +1514,7 @@ opkg_install_pkg(pkg_t *pkg, int from_upgrade) sigprocmask(SIG_UNBLOCK, &newset, &oldset); pkg_vec_free (replacees); return 0; - + UNWIND_POSTRM_UPGRADE_OLD_PKG: postrm_upgrade_old_pkg_unwind(pkg, old_pkg);