+ char *file_sha256, *pkg_sha256;
+#endif
+ sigset_t newset, oldset;
+ const char *local_filename;
+ time_t now;
+
+ if (from_upgrade)
+ message = 1; /* Coming from an upgrade, and should change the output message */
+
+ opkg_msg(DEBUG2, "Calling pkg_arch_supported.\n");
+
+ if (!pkg_arch_supported(pkg)) {
+ opkg_msg(ERROR,
+ "INTERNAL ERROR: architecture %s for pkg %s is unsupported.\n",
+ pkg_get_architecture(pkg), pkg->name);
+ return -1;
+ }
+ 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",
+ pkg->name, pkg->dest->name);
+ return 0;
+ }
+
+ if (pkg->dest == NULL) {
+ pkg->dest = conf->default_dest;
+ }
+
+ old_pkg = pkg_hash_fetch_installed_by_name(pkg->name);
+
+ err = opkg_install_check_downgrade(pkg, old_pkg, message);
+ if (err)
+ return -1;
+
+ pkg->state_want = SW_INSTALL;
+ 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)
+ return 0;
+
+ err = verify_pkg_installable(pkg);
+ if (err)
+ return -1;
+
+ local_filename = pkg_get_string(pkg, PKG_LOCAL_FILENAME);
+
+ if (local_filename == NULL) {
+ 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",
+ pkg->name);
+ return -1;
+ }
+
+ local_filename = pkg_get_string(pkg, PKG_LOCAL_FILENAME);
+ }
+
+ /* check that the repository is valid */
+#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 */
+ 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(list_file_name, sig_file_name)) {
+ opkg_msg(ERROR,
+ "Failed to verify the signature of %s.\n",
+ list_file_name);
+ 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);
+ if (!conf->force_signature)
+ return -1;
+ }
+
+ free(lists_dir);
+ free(list_file_name);
+ free(sig_file_name);
+ }
+#endif
+
+#ifdef HAVE_MD5
+ /* Check for md5 values */
+ pkg_md5 = pkg_get_md5(pkg);
+ if (pkg_md5) {
+ file_md5 = file_md5sum_alloc(local_filename);
+ if (file_md5 && strcmp(file_md5, pkg_md5)) {
+ 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);
+ }