/** * asb_package_compare: * @pkg1: A #AsbPackage * @pkg2: A #AsbPackage * * Compares one package with another. * * Returns: +1 for @pkg1 newer, 0 for the same and -1 if @pkg2 is newer * * Since: 0.1.0 **/ gint asb_package_compare (AsbPackage *pkg1, AsbPackage *pkg2) { AsbPackagePrivate *priv1 = GET_PRIVATE (pkg1); AsbPackagePrivate *priv2 = GET_PRIVATE (pkg2); AsbPackageClass *klass = ASB_PACKAGE_GET_CLASS (pkg1); gint rc; /* class-specific compare method */ if (klass->compare != NULL) return klass->compare (pkg1, pkg2); /* check name */ rc = g_strcmp0 (priv1->name, priv2->name); if (rc != 0) return rc; /* check epoch */ if (priv1->epoch < priv2->epoch) return -1; if (priv1->epoch > priv2->epoch) return 1; /* check version */ rc = as_utils_vercmp (priv1->version, priv2->version); if (rc != 0) return rc; /* check release */ rc = as_utils_vercmp (priv1->release, priv2->release); if (rc != 0) return rc; /* check arch */ return g_strcmp0 (priv1->arch, priv2->arch); }
/** * fu_util_install_prepared: **/ static gboolean fu_util_install_prepared (FuUtilPrivate *priv, gchar **values, GError **error) { gint vercmp; guint cnt = 0; guint i; const gchar *tmp; _cleanup_ptrarray_unref_ GPtrArray *devices = NULL; _cleanup_object_unref_ FuPending *pending = NULL; /* do this first to avoid a loop if this tool segfaults */ g_unlink (FU_OFFLINE_TRIGGER_FILENAME); if (g_strv_length (values) != 0) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Invalid arguments: none expected"); return FALSE; } /* ensure root user */ if (getuid () != 0 || geteuid () != 0) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "This function can only be used as root"); return FALSE; } /* get prepared updates */ pending = fu_pending_new (); devices = fu_pending_get_devices (pending, error); if (devices == NULL) return FALSE; /* apply each update */ for (i = 0; i < devices->len; i++) { FuDevice *device; device = g_ptr_array_index (devices, i); /* check not already done */ tmp = fu_device_get_metadata (device, FU_DEVICE_KEY_PENDING_STATE); if (g_strcmp0 (tmp, "scheduled") != 0) continue; /* tell the user what's going to happen */ vercmp = as_utils_vercmp (fu_device_get_metadata (device, FU_DEVICE_KEY_VERSION_OLD), fu_device_get_metadata (device, FU_DEVICE_KEY_VERSION_NEW)); if (vercmp == 0) { /* TRANSLATORS: the first replacement is a display name * e.g. "ColorHugALS" and the second is a version number * e.g. "1.2.3" */ g_print (_("Reinstalling %s with %s... "), fu_device_get_display_name (device), fu_device_get_metadata (device, FU_DEVICE_KEY_VERSION_NEW)); } else if (vercmp > 0) { /* TRANSLATORS: the first replacement is a display name * e.g. "ColorHugALS" and the second and third are * version numbers e.g. "1.2.3" */ g_print (_("Downgrading %s from %s to %s... "), fu_device_get_display_name (device), fu_device_get_metadata (device, FU_DEVICE_KEY_VERSION_OLD), fu_device_get_metadata (device, FU_DEVICE_KEY_VERSION_NEW)); } else if (vercmp < 0) { /* TRANSLATORS: the first replacement is a display name * e.g. "ColorHugALS" and the second and third are * version numbers e.g. "1.2.3" */ g_print (_("Updating %s from %s to %s... "), fu_device_get_display_name (device), fu_device_get_metadata (device, FU_DEVICE_KEY_VERSION_OLD), fu_device_get_metadata (device, FU_DEVICE_KEY_VERSION_NEW)); } if (!fu_util_install_internal (priv, fu_device_get_id (device), fu_device_get_metadata (device, FU_DEVICE_KEY_FILENAME_CAB), error)) return FALSE; cnt++; } /* nothing to do */ if (cnt == 0) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOTHING_TO_DO, "No updates prepared"); return FALSE; } /* reboot */ fu_util_offline_update_reboot (); g_print ("%s\n", _("Done!")); return TRUE; }
/** * as_require_version_compare: * @require: a #AsRequire instance. * @version: a version number, e.g. `0.1.3` * @error: A #GError or %NULL * * Compares the version number of the requirement with a predicate. * * Returns: %TRUE if the predicate was true * * Since: 0.6.7 **/ gboolean as_require_version_compare (AsRequire *require, const gchar *version, GError **error) { AsRequirePrivate *priv = GET_PRIVATE (require); gboolean ret = FALSE; gint rc = 0; switch (priv->compare) { case AS_REQUIRE_COMPARE_EQ: rc = as_utils_vercmp (version, priv->version); ret = rc == 0; break; case AS_REQUIRE_COMPARE_NE: rc = as_utils_vercmp (version, priv->version); ret = rc != 0; break; case AS_REQUIRE_COMPARE_LT: rc = as_utils_vercmp (version, priv->version); ret = rc < 0; break; case AS_REQUIRE_COMPARE_GT: rc = as_utils_vercmp (version, priv->version); ret = rc > 0; break; case AS_REQUIRE_COMPARE_LE: rc = as_utils_vercmp (version, priv->version); ret = rc <= 0; break; case AS_REQUIRE_COMPARE_GE: rc = as_utils_vercmp (version, priv->version); ret = rc >= 0; break; case AS_REQUIRE_COMPARE_GLOB: ret = fnmatch (priv->version, version, 0) == 0; break; case AS_REQUIRE_COMPARE_REGEX: ret = g_regex_match_simple (priv->version, version, 0, 0); break; default: break; } /* could not compare */ if (rc == G_MAXINT) { g_set_error (error, AS_UTILS_ERROR, AS_UTILS_ERROR_FAILED, "failed to compare [%s] and [%s]", priv->version, version); return FALSE; } /* set error */ if (!ret && error != NULL) { g_set_error (error, AS_UTILS_ERROR, AS_UTILS_ERROR_FAILED, "failed predicate [%s %s %s]", priv->version, as_require_compare_to_string (priv->compare), version); } return ret; }