X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=libopkg%2Fopkg_install.c;h=3ee72424ed1de8c35c0b46e67142920dcc9ea77b;hb=0029afd9026a9f82c68c86a81be306ff835a30d5;hp=3a1d69d46467b228eb3c9febecc8ec34b4ee9429;hpb=b06a66aaeddc129a3a8c08f0ac45be6d7f2c5199;p=oweals%2Fopkg-lede.git diff --git a/libopkg/opkg_install.c b/libopkg/opkg_install.c index 3a1d69d..3ee7242 100644 --- a/libopkg/opkg_install.c +++ b/libopkg/opkg_install.c @@ -36,7 +36,7 @@ typedef void (*sighandler_t)(int); #include "opkg_utils.h" #include "opkg_message.h" -#include "opkg_state.h" +#include "opkg_cmd.h" #include "opkg_defines.h" #include "sprintf_alloc.h" @@ -44,6 +44,7 @@ typedef void (*sighandler_t)(int); #include "str_util.h" #include "xsystem.h" #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); @@ -68,8 +69,6 @@ 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 cleanup_temporary_files(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); @@ -85,11 +84,8 @@ int opkg_install_from_file(opkg_conf_t *conf, const char *filename) char *old_version, *new_version; pkg = pkg_new(); - if (pkg == NULL) { - return ENOMEM; - } - err = pkg_init_from_file(pkg, filename); + err = pkg_init_from_file(conf, pkg, filename); if (err) { return err; } @@ -105,8 +101,6 @@ int opkg_install_from_file(opkg_conf_t *conf, const char *filename) pkg = hash_insert_pkg(&conf->pkg_hash, pkg, 1,conf); old = pkg_hash_fetch_installed_by_name(&conf->pkg_hash, pkg->name); - pkg->local_filename = strdup(filename); - if (old) { old_version = pkg_version_str_alloc(old); new_version = pkg_version_str_alloc(pkg); @@ -138,7 +132,7 @@ int opkg_install_from_file(opkg_conf_t *conf, const char *filename) opkg_error_t opkg_install_by_name(opkg_conf_t *conf, const char *pkg_name) { - int cmp, err; + int cmp, err = 0; pkg_t *old, *new; char *old_version, *new_version; @@ -208,6 +202,8 @@ opkg_error_t opkg_install_by_name(opkg_conf_t *conf, const char *pkg_name) 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 @@ -431,11 +427,13 @@ static int check_conflicts_for(opkg_conf_t *conf, pkg_t *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(new_pkg); - str_list_elt_t *iter; + str_list_t *new_list = pkg_get_installed_files(conf, new_pkg); + str_list_elt_t *iter, *niter; - for (iter = new_list->head; iter; iter = iter->next) { - char *new_file = iter->data; + 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(conf, new_file); if (!new_file) opkg_message(conf, OPKG_ERROR, "Null new_file for new_pkg=%s\n", new_pkg->name); @@ -443,9 +441,11 @@ static int update_file_ownership(opkg_conf_t *conf, pkg_t *new_pkg, pkg_t *old_p file_hash_set_file_owner(conf, new_file, new_pkg); } if (old_pkg) { - str_list_t *old_list = pkg_get_installed_files(old_pkg); - for (iter = old_list->head; iter; iter = iter->next) { - char *old_file = iter->data; + str_list_t *old_list = pkg_get_installed_files(conf, old_pkg); + 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(conf, old_file); if (owner == old_pkg) { /* obsolete */ @@ -471,9 +471,11 @@ static int verify_pkg_installable(opkg_conf_t *conf, pkg_t *pkg) * 3) return a proper error code instead of 1 */ int comp_size, blocks_available; + char *root_dir; if (!conf->force_space && pkg->installed_size != NULL) { - blocks_available = get_available_blocks(conf->default_dest->root_dir); + root_dir = pkg->dest ? pkg->dest->root_dir : conf->default_dest->root_dir; + blocks_available = get_available_blocks(root_dir); comp_size = strtoul(pkg->installed_size, NULL, 0); /* round up a blocks count without doing fancy-but-slow casting jazz */ @@ -482,7 +484,7 @@ static int verify_pkg_installable(opkg_conf_t *conf, pkg_t *pkg) if (comp_size >= blocks_available) { opkg_message(conf, OPKG_ERROR, "Only have %d available blocks on filesystem %s, pkg %s needs %d\n", - blocks_available, conf->default_dest->root_dir, pkg->name, comp_size); + blocks_available, root_dir, pkg->name, comp_size); return ENOSPC; } } @@ -517,7 +519,7 @@ static int unpack_pkg_control_files(opkg_conf_t *conf, pkg_t *pkg) move all of unpack_pkg_control_files to that function. */ /* Don't need to re-read conffiles if we already have it */ - if (pkg->conffiles.head) { + if (!nv_pair_list_empty(&pkg->conffiles)) { return 0; } @@ -571,57 +573,92 @@ static int unpack_pkg_control_files(opkg_conf_t *conf, pkg_t *pkg) return 0; } -static int pkg_remove_orphan_dependent(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg) +/* + * Remove packages which were auto_installed due to a dependency by old_pkg, + * which are no longer a dependency in the new (upgraded) pkg. + */ +static int +pkg_remove_orphan_dependent(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg) { - int i, j, found; - char *buf, *d_str; - pkg_t *p; - if (!old_pkg) - return 0; - if (!pkg) { - fprintf(stderr, "pkg shall not be NULL here. please send to the bugzilla!! [%s %d]\n", __FILE__, __LINE__); - return -1; - } - if (old_pkg->depends_count == 0) - return 0; - for (i=0;idepends_count;i++) { - found = 0; - for (j=0;jdepends_count;j++) { - if (!strcmp(old_pkg->depends_str[i], pkg->depends_str[j])) { - found = 1; - break; - } - } - if (found) - continue; - d_str = old_pkg->depends_str[i]; - buf = calloc (1, strlen (d_str) + 1); - j=0; - while (d_str[j] != '\0' && d_str[j] != ' ') { - buf[j]=d_str[j]; - ++j; - } - buf[j]='\0'; - buf = realloc (buf, strlen (buf) + 1); - p = pkg_hash_fetch_installed_by_name (&conf->pkg_hash, buf); - if (!p) { - fprintf(stderr, "The pkg %s had been removed!!\n", buf); - free(buf); - continue; - } - if (p->auto_installed) { - int deps; - abstract_pkg_t **dependents; - deps = pkg_has_installed_dependents(conf, NULL, p, &dependents); - if (deps == 0) { - opkg_message (conf, OPKG_NOTICE,"%s was autoinstalled but is now orphaned, remove it.\n", buf); - opkg_remove_pkg(conf, p, 0); - } else - opkg_message (conf, OPKG_INFO, "%s was autoinstalled and is still required by %d installed packages\n", buf, deps); - } - free(buf); - } - return 0; + int i, j, k, l, found; + int n_deps; + pkg_t *p; + struct compound_depend *cd0, *cd1; + abstract_pkg_t **dependents; + + int count0 = old_pkg->pre_depends_count + + old_pkg->depends_count + + old_pkg->recommends_count + + old_pkg->suggests_count; + int count1 = pkg->pre_depends_count + + pkg->depends_count + + pkg->recommends_count + + pkg->suggests_count; + + for (i=0; idepends[i]; + if (cd0->type != DEPEND) + continue; + for (j=0; jpossibility_count; j++) { + + found = 0; + + for (k=0; kdepends[i]; + if (cd1->type != DEPEND) + continue; + for (l=0; lpossibility_count; l++) { + if (cd0->possibilities[j] + == cd1->possibilities[l]) { + found = 1; + break; + } + } + if (found) + break; + } + + if (found) + continue; + + /* + * old_pkg has a dependency that pkg does not. + */ + p = pkg_hash_fetch_installed_by_name (&conf->pkg_hash, + cd0->possibilities[j]->pkg->name); + + if (!p) + continue; + + if (!p->auto_installed) + continue; + + n_deps = pkg_has_installed_dependents(conf, NULL, p, + &dependents); + n_deps--; /* don't count old_pkg */ + + if (n_deps == 0) { + opkg_message (conf, OPKG_NOTICE, + "%s was autoinstalled and is " + "now orphaned, removing.\n", + p->name); + + /* p has one installed dependency (old_pkg), + * which we need to ignore during removal. */ + p->state_flag |= SF_REPLACE; + + opkg_remove_pkg(conf, p, 0); + } else + opkg_message(conf, OPKG_INFO, + "%s was autoinstalled and is " + "still required by %d " + "installed packages.\n", + p->name, n_deps); + + } + } + + return 0; } /* returns number of installed replacees */ @@ -679,12 +716,6 @@ int pkg_remove_installed_replacees_unwind(opkg_conf_t *conf, pkg_vec_t *replacee return 0; } -int caught_sigint = 0; -static void opkg_install_pkg_sigint_handler(int sig) -{ - caught_sigint = sig; -} - /* 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) { @@ -760,8 +791,10 @@ int opkg_install_pkg(opkg_conf_t *conf, pkg_t *pkg, int from_upgrade) abstract_pkg_t *ab_pkg = NULL; int old_state_flag; char* file_md5; - char *pkgid; - +#ifdef HAVE_SHA256 + char* file_sha256; +#endif + if ( from_upgrade ) message = 1; /* Coming from an upgrade, and should change the output message */ @@ -828,11 +861,11 @@ int opkg_install_pkg(opkg_conf_t *conf, pkg_t *pkg, int from_upgrade) } /* check that the repository is valid */ - #if HAVE_GPGME + #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 (pkg->src) + if (conf->check_signature && pkg->src) { sprintf_alloc (&lists_dir, "%s", (conf->restrict_to_default_dest) @@ -843,8 +876,15 @@ int opkg_install_pkg(opkg_conf_t *conf, pkg_t *pkg, int from_upgrade) if (file_exists (sig_file_name)) { - if (opkg_verify_file (conf, list_file_name, 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); @@ -857,7 +897,7 @@ int opkg_install_pkg(opkg_conf_t *conf, pkg_t *pkg, int from_upgrade) if (pkg->md5sum) { file_md5 = file_md5sum_alloc(pkg->local_filename); - if (strcmp(file_md5, pkg->md5sum)) + 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", @@ -865,8 +905,27 @@ int opkg_install_pkg(opkg_conf_t *conf, pkg_t *pkg, int from_upgrade) free(file_md5); return OPKG_INSTALL_ERR_MD5; } - free(file_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); @@ -881,33 +940,27 @@ int opkg_install_pkg(opkg_conf_t *conf, pkg_t *pkg, int from_upgrade) 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); - 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); - } + + 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); + 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 @@ -986,20 +1039,13 @@ int opkg_install_pkg(opkg_conf_t *conf, pkg_t *pkg, int from_upgrade) 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); + sigprocmask(SIG_UNBLOCK, &newset, &oldset); pkg_vec_free (replacees); return 0; @@ -1019,21 +1065,14 @@ int opkg_install_pkg(opkg_conf_t *conf, pkg_t *pkg, int from_upgrade) 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); + + sigprocmask(SIG_UNBLOCK, &newset, &oldset); pkg_vec_free (replacees); return OPKG_ERR_UNKNOWN; } - opkg_set_current_state (conf, OPKG_STATE_NONE, NULL); } static int prerm_upgrade_old_pkg(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg) @@ -1108,7 +1147,7 @@ static int preinst_configure(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg) sprintf_alloc(&preinst_args, "install %s", pkg_version); free(pkg_version); } else { - preinst_args = strdup("install"); + preinst_args = xstrdup("install"); } err = pkg_run_script(conf, pkg, "preinst", preinst_args); @@ -1144,7 +1183,7 @@ static int backup_modified_conffiles(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_p /* Backup all modified conffiles */ if (old_pkg) { - for (iter = old_pkg->conffiles.head; iter; iter = iter->next) { + 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; @@ -1162,9 +1201,9 @@ static int backup_modified_conffiles(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_p } /* Backup all conffiles that were not conffiles in old_pkg */ - for (iter = pkg->conffiles.head; iter; iter = iter->next) { + for (iter = nv_pair_list_first(&pkg->conffiles); iter; iter = nv_pair_list_next(&pkg->conffiles, iter)) { char *cf_name; - cf = iter->data; + cf = (conffile_t *)iter->data; cf_name = root_filename_alloc(conf, cf->name); /* Ignore if this was a conffile in old_pkg as well */ if (pkg_get_conffile(old_pkg, cf->name)) { @@ -1188,13 +1227,13 @@ static int backup_modified_conffiles_unwind(opkg_conf_t *conf, pkg_t *pkg, pkg_t conffile_list_elt_t *iter; if (old_pkg) { - for (iter = old_pkg->conffiles.head; iter; iter = iter->next) { - backup_remove(iter->data->name); + for (iter = nv_pair_list_first(&old_pkg->conffiles); iter; iter = nv_pair_list_next(&old_pkg->conffiles, iter)) { + backup_remove(((nv_pair_t *)iter->data)->name); } } - for (iter = pkg->conffiles.head; iter; iter = iter->next) { - backup_remove(iter->data->name); + for (iter = nv_pair_list_first(&pkg->conffiles); iter; iter = nv_pair_list_next(&pkg->conffiles, iter)) { + backup_remove(((nv_pair_t *)iter->data)->name); } return 0; @@ -1217,14 +1256,16 @@ static int check_data_file_clashes(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg other package. */ str_list_t *files_list; - str_list_elt_t *iter; + str_list_elt_t *iter, *niter; int clashes = 0; - files_list = pkg_get_installed_files(pkg); - for (iter = files_list->head; iter; iter = iter->next) { + files_list = pkg_get_installed_files(conf, pkg); + 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 = iter->data; + char *filename = (char *) iter->data; root_filename = root_filename_alloc(conf, filename); if (file_exists(root_filename) && (! file_is_dir(root_filename))) { pkg_t *owner; @@ -1304,25 +1345,33 @@ static int check_data_file_clashes_change(opkg_conf_t *conf, pkg_t *pkg, pkg_t * @@@ To change after 1.0 release. */ str_list_t *files_list; - str_list_elt_t *iter; + str_list_elt_t *iter, *niter; + + char *root_filename = NULL; int clashes = 0; - files_list = pkg_get_installed_files(pkg); - for (iter = files_list->head; iter; iter = iter->next) { - char *root_filename; - char *filename = iter->data; + files_list = pkg_get_installed_files(conf, pkg); + 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) { + free(root_filename); + root_filename = NULL; + } root_filename = root_filename_alloc(conf, filename); if (file_exists(root_filename) && (! file_is_dir(root_filename))) { pkg_t *owner; + owner = file_hash_get_file_owner(conf, filename); + if (conf->force_overwrite) { /* but we need to change who owns this file */ file_hash_set_file_owner(conf, filename, pkg); continue; } - owner = file_hash_get_file_owner(conf, filename); /* Pre-existing files are OK if owned by a package replaced by new pkg. */ if (owner) { @@ -1336,7 +1385,10 @@ static int check_data_file_clashes_change(opkg_conf_t *conf, pkg_t *pkg, pkg_t * } } - free(root_filename); + } + if (root_filename) { + free(root_filename); + root_filename = NULL; } pkg_free_installed_files(pkg); @@ -1377,24 +1429,30 @@ static int remove_obsolesced_files(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg str_list_elt_t *of; str_list_t *new_files; str_list_elt_t *nf; + hash_table_t new_files_table; if (old_pkg == NULL) { return 0; } - old_files = pkg_get_installed_files(old_pkg); - new_files = pkg_get_installed_files(pkg); + old_files = pkg_get_installed_files(conf, old_pkg); + new_files = pkg_get_installed_files(conf, pkg); + + new_files_table.entries = NULL; + hash_table_init("new_files" , &new_files_table, 20); + for (nf = str_list_first(new_files); nf; nf = str_list_next(new_files, nf)) { + if (nf && nf->data) + hash_table_insert(&new_files_table, nf->data, nf->data); + } - for (of = old_files->head; of; of = of->next) { + for (of = str_list_first(old_files); of; of = str_list_next(old_files, of)) { pkg_t *owner; char *old, *new; - old = of->data; - for (nf = new_files->head; nf; nf = nf->next) { - new = nf->data; - if (strcmp(old, new) == 0) { - goto NOT_OBSOLETE; - } - } + old = (char *)of->data; + new = (char *) hash_table_get (&new_files_table, old); + if (new) + continue; + if (file_is_dir(old)) { continue; } @@ -1414,53 +1472,20 @@ static int remove_obsolesced_files(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg strerror(errno)); } } - - NOT_OBSOLETE: - ; } + hash_table_deinit(&new_files_table); pkg_free_installed_files(old_pkg); pkg_free_installed_files(pkg); return 0; } -static int remove_obsolete_maintainer_scripts(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg) -{ - int i; - int err = 0; - char *globpattern; - glob_t globbuf; - if (0) { - if (!pkg->dest) { - opkg_message(conf, OPKG_ERROR, "%s: no dest for package %s\n", __FUNCTION__, pkg->name); - return -1; - } - sprintf_alloc(&globpattern, "%s/%s.*", pkg->dest->info_dir, pkg->name); - err = glob(globpattern, 0, NULL, &globbuf); - free(globpattern); - if (err) { - return err; - } - /* XXXX this should perhaps only remove the ones that are not overwritten in new package. Jamey 11/11/2003 */ - for (i = 0; i < globbuf.gl_pathc; i++) { - opkg_message(conf, OPKG_DEBUG, "Removing control file %s from old_pkg %s\n", - globbuf.gl_pathv[i], old_pkg->name); - if (!conf->noaction) - unlink(globbuf.gl_pathv[i]); - } - globfree(&globbuf); - } - return err; -} - static int install_maintainer_scripts(opkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg) { int ret; char *prefix; - if (old_pkg) - remove_obsolete_maintainer_scripts(conf, pkg, old_pkg); sprintf_alloc(&prefix, "%s.", pkg->name); ret = pkg_extract_control_files_to_dir_with_prefix(pkg, pkg->dest->info_dir, @@ -1543,15 +1568,13 @@ static int resolve_conffiles(opkg_conf_t *conf, pkg_t *pkg) conffile_list_elt_t *iter; conffile_t *cf; char *cf_backup; + char *md5sum; - char *md5sum; - - if (conf->noaction) return 0; - for (iter = pkg->conffiles.head; iter; iter = iter->next) { + for (iter = nv_pair_list_first(&pkg->conffiles); iter; iter = nv_pair_list_next(&pkg->conffiles, iter)) { char *root_filename; - cf = iter->data; + cf = (conffile_t *)iter->data; root_filename = root_filename_alloc(conf, cf->name); /* Might need to initialize the md5sum for each conffile */ @@ -1567,18 +1590,21 @@ static int resolve_conffiles(opkg_conf_t *conf, pkg_t *pkg) cf_backup = backup_filename_alloc(root_filename); - if (file_exists(cf_backup)) { - /* Let's compute md5 to test if files are changed */ - md5sum = file_md5sum_alloc(cf_backup); - if (strcmp( cf->value,md5sum) != 0 ) { - if (conf->force_defaults - || user_prefers_old_conffile(cf->name, cf_backup) ) { - rename(cf_backup, root_filename); - } - } - unlink(cf_backup); - free(md5sum); - } + 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 ) { + if (conf->force_maintainer) { + opkg_message(conf, OPKG_NOTICE, "Conffile %s using maintainer's setting.\n", cf_backup); + } else if (conf->force_defaults + || user_prefers_old_conffile(root_filename, cf_backup) ) { + rename(cf_backup, root_filename); + } + } + unlink(cf_backup); + if (md5sum) + free(md5sum); + } free(cf_backup); free(root_filename); @@ -1609,6 +1635,10 @@ static int user_prefers_old_conffile(const char *file_name, const char *backup) " 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) { @@ -1617,13 +1647,8 @@ static int user_prefers_old_conffile(const char *file_name, const char *backup) } if (strcmp(response, "d") == 0) { - char *cmd; - - free(response); - /* XXX: BUG rewrite to use exec or busybox's internal diff */ - sprintf_alloc(&cmd, "diff -u %s %s", backup, file_name); - xsystem(cmd); - free(cmd); + 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); @@ -1635,57 +1660,6 @@ static int user_prefers_old_conffile(const char *file_name, const char *backup) } } -/* XXX: CLEANUP: I'd like to move all of the code for - creating/cleaning pkg->tmp_unpack_dir directly into pkg.c. (Then, - it would make sense to cleanup pkg->tmp_unpack_dir directly from - pkg_deinit for example). */ -static int cleanup_temporary_files(opkg_conf_t *conf, pkg_t *pkg) -{ - DIR *tmp_dir; - struct dirent *dirent; - char *tmp_file; - -#ifdef OPKG_DEBUG_NO_TMP_CLEANUP -#error - opkg_message(conf, OPKG_DEBUG, - "%s: Not cleaning up %s since opkg compiled with OPKG_DEBUG_NO_TMP_CLEANUP\n", - __FUNCTION__, pkg->tmp_unpack_dir); - return 0; -#endif - - if (pkg->tmp_unpack_dir && file_is_dir(pkg->tmp_unpack_dir)) { - tmp_dir = opendir(pkg->tmp_unpack_dir); - if (tmp_dir) { - while (1) { - dirent = readdir(tmp_dir); - if (dirent == NULL) { - break; - } - sprintf_alloc(&tmp_file, "%s/%s", - pkg->tmp_unpack_dir, dirent->d_name); - if (! file_is_dir(tmp_file)) { - unlink(tmp_file); - } - free(tmp_file); - } - closedir(tmp_dir); - rmdir(pkg->tmp_unpack_dir); - free(pkg->tmp_unpack_dir); - pkg->tmp_unpack_dir = NULL; - } - } - - opkg_message(conf, OPKG_INFO, "cleanup_temporary_files: pkg=%s local_filename=%s tmp_dir=%s\n", - pkg->name, pkg->local_filename, conf->tmp_dir); - if (pkg->local_filename && strncmp(pkg->local_filename, conf->tmp_dir, strlen(conf->tmp_dir)) == 0) { - unlink(pkg->local_filename); - free(pkg->local_filename); - pkg->local_filename = NULL; - } - - return 0; -} - static char *backup_filename_alloc(const char *file_name) { char *backup;