X-Git-Url: https://git.librecmc.org/?p=oweals%2Fopkg-lede.git;a=blobdiff_plain;f=libopkg%2Fopkg_install.c;h=0db0acdf84e7d6f297da9f690e82aa8d4a41e15e;hp=484c9e9bd56ca6fea19ab164e842f59de3a13ae2;hb=733eb7729491810c346bbbecd31051ecc118fd82;hpb=bc5bbb7265a7d4d3905efd2cbc75a4cb5691ceb8 diff --git a/libopkg/opkg_install.c b/libopkg/opkg_install.c index 484c9e9..0db0acd 100644 --- a/libopkg/opkg_install.c +++ b/libopkg/opkg_install.c @@ -21,6 +21,7 @@ #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) { @@ -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,7 +317,7 @@ 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,r, err = 0; int n_deps; @@ -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++) { @@ -365,7 +387,7 @@ pkg_remove_orphan_dependent(pkg_t *pkg, pkg_t *old_pkg) 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", @@ -438,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); @@ -447,12 +469,12 @@ 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) { if(!conf->download_only) @@ -467,27 +489,18 @@ opkg_install_check_downgrade(pkg_t *pkg, pkg_t *old_pkg, int message) 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 ") ); @@ -507,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 @@ -621,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) { @@ -674,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); @@ -740,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 @@ -748,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); @@ -816,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); @@ -853,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) { @@ -877,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", @@ -971,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) { @@ -1009,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 @@ -1033,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) { @@ -1046,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) @@ -1072,7 +1082,7 @@ resolve_conffiles(pkg_t *pkg) conffile_list_elt_t *iter; conffile_t *cf; char *cf_backup; - char *md5sum; + char *chksum; if (conf->noaction) return 0; @@ -1083,7 +1093,7 @@ resolve_conffiles(pkg_t *pkg) /* Might need to initialize the md5sum for each conffile */ if (cf->value == NULL) { - cf->value = file_md5sum_alloc(root_filename); + cf->value = file_sha256sum_alloc(root_filename); } if (!file_exists(root_filename)) { @@ -1095,15 +1105,23 @@ resolve_conffiles(pkg_t *pkg) if (file_exists(cf_backup)) { /* Let's compute md5 to test if files are changed */ - md5sum = file_md5sum_alloc(cf_backup); - if (md5sum && cf->value && strcmp(cf->value,md5sum) != 0 ) { +#ifdef HAVE_MD5 + if(cf->value && strlen(cf->value) > 33) { + chksum = file_sha256sum_alloc(cf_backup); + } else { + chksum = file_md5sum_alloc(cf_backup); + } +#else + chksum = file_sha256sum_alloc(cf_backup); +#endif + if (chksum && cf->value && strcmp(cf->value,chksum) != 0 ) { if (conf->force_maintainer) { opkg_msg(NOTICE, "Conffile %s using maintainer's setting.\n", cf_backup); } 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); @@ -1113,8 +1131,8 @@ resolve_conffiles(pkg_t *pkg) } } unlink(cf_backup); - if (md5sum) - free(md5sum); + if (chksum) + free(chksum); } free(cf_backup); @@ -1136,15 +1154,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) { @@ -1154,16 +1174,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); @@ -1179,7 +1199,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); @@ -1190,7 +1210,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) @@ -1207,7 +1227,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"); @@ -1217,12 +1237,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; } @@ -1238,21 +1258,21 @@ opkg_install_pkg(pkg_t *pkg, int from_upgrade) 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; @@ -1276,7 +1296,7 @@ opkg_install_pkg(pkg_t *pkg, int from_upgrade) } /* check that the repository is valid */ - #if defined(HAVE_GPGME) || defined(HAVE_OPENSSL) + #if defined(HAVE_GPGME) || defined(HAVE_OPENSSL) || defined(HAVE_USIGN) char *list_file_name, *sig_file_name, *lists_dir; /* check to ensure the package has come from a repository */ @@ -1294,13 +1314,15 @@ opkg_install_pkg(pkg_t *pkg, int from_upgrade) if (opkg_verify_file (list_file_name, sig_file_name)){ opkg_msg(ERROR, "Failed to verify the signature of %s.\n", list_file_name); - return -1; + if (!conf->force_signature) + return -1; } }else{ opkg_msg(ERROR, "Signature file is missing for %s. " "Perhaps you need to run 'opkg update'?\n", pkg->name); - return -1; + if (!conf->force_signature) + return -1; } free (lists_dir); @@ -1309,22 +1331,31 @@ opkg_install_pkg(pkg_t *pkg, int from_upgrade) } #endif +#ifdef HAVE_MD5 /* Check for md5 values */ if (pkg->md5sum) { 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); } +#endif #ifdef HAVE_SHA256 /* Check for sha256 value */ @@ -1386,11 +1417,13 @@ opkg_install_pkg(pkg_t *pkg, int from_upgrade) opkg_state_changed++; pkg->state_flag |= SF_FILELIST_CHANGED; - if (old_pkg) + if (old_pkg) { pkg_remove_orphan_dependent(pkg, old_pkg); - + old_pkg->is_upgrade = 1; + pkg->is_upgrade = 1; + } /* 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) @@ -1424,7 +1457,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) { @@ -1441,13 +1474,13 @@ 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); } - opkg_msg(INFO, "Installing maintainer scripts.\n"); + opkg_msg(INFO, "%s maintainer scripts.\n", (pkg->is_upgrade) ? ("Upgrading") : ("Installing")); if (install_maintainer_scripts(pkg, old_pkg)) { opkg_msg(ERROR, "Failed to extract maintainer scripts for %s." " Package debris may remain!\n", @@ -1483,9 +1516,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); @@ -1496,7 +1528,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);