コード例 #1
0
ファイル: version.c プロジェクト: amogrid/redcurrant
void
version_debug(const gchar *tag, GTree *versions)
{
	if (!GRID_TRACE_ENABLED())
		return;

	(void) tag;
	gchar *s = version_dump(versions);
	GRID_TRACE("%s %s (%s)", tag, s, __FUNCTION__);
	g_free(s);
}
コード例 #2
0
ファイル: version.c プロジェクト: Eppo791906066/gtk-gnutella
/**
 * Check version of servent, and if it's a gtk-gnutella more recent than we
 * are, record that fact and change the status bar.
 *
 * The `addr' is being passed solely for the tok_version_valid() call.
 *
 * @returns TRUE if we properly checked the version, FALSE if we got something
 * looking as gtk-gnutella but which failed the token-based sanity checks.
 */
bool
version_check(const char *str, const char *token, const host_addr_t addr)
{
	version_t their_version;
	version_ext_t their_version_ext;
	version_t *target_version;
	int cmp;
	const char *version;
	const char *end;
	bool extended;

	if (!version_parse(str, &their_version, &end))
		return TRUE;			/* Not gtk-gnutella, or unparseable */

	/*
	 * Check for extended version information (git commit ID, dirty status).
	 */

	ZERO(&their_version_ext);
	extended = version_ext_parse(end, &their_version_ext);
	if (!extended) {
		/* Structure could have been partially filled */
		ZERO(&their_version_ext);
	}

	/*
	 * Is their version a development one, or a release?
	 */

	if (their_version.tag == 'u')
		target_version = &last_dev_version;
	else
		target_version = &last_rel_version;

	cmp = version_cmp(target_version, &their_version);

	if (GNET_PROPERTY(version_debug) > 1)
		version_dump(str, &their_version,
			cmp == 0 ? "=" :
			cmp > 0 ? "-" : "+");

	/*
	 * Check timestamp.
	 */

	version_stamp(str, &their_version);
	their_version_ext.version = their_version;		/* Struct copy */

	if (GNET_PROPERTY(version_debug) > 3)
		g_debug("VERSION time=%d", (int) their_version.timestamp);

	/*
	 * If version claims something older than TOKEN_START_DATE, then
	 * there must be a token present.
	 */

	if (delta_time(their_version.timestamp, 0) >= TOKEN_START_DATE) {
		tok_error_t error;

		if (token == NULL) {
            if (GNET_PROPERTY(version_debug)) {
                g_debug("got GTKG vendor string \"%s\" without token!", str);
            }
			return FALSE;	/* Can't be correct */
		}

		error = tok_version_valid(str, token, strlen(token), addr);

		/*
		 * Unfortunately, if our token has expired, we can no longer
		 * validate the tokens of the remote peers, since they are using
		 * a different set of keys.
		 *
		 * This means an expired GTKG will blindly trust well-formed remote
		 * tokens at face value.  But it's their fault, they should not run
		 * an expired version!
		 *		--RAM, 2005-12-21
		 */

		if (error == TOK_BAD_KEYS && tok_is_ancient(tm_time()))
			error = TOK_OK;		/* Our keys have expired, cannot validate */

		if (error != TOK_OK) {
            if (GNET_PROPERTY(version_debug)) {
                g_debug("vendor string \"%s\" [%s] has wrong token "
                    "\"%s\": %s ", str, host_addr_to_string(addr), token,
                    tok_strerror(error));
            }
			return FALSE;
		}

		/*
		 * OK, so now we know we can "trust" this version string as being
		 * probably genuine.  It makes sense to extract version information
		 * out of it.
		 */
	}

	if (cmp > 0)			/* We're more recent */
		return TRUE;

	/*
	 * If timestamp is greater and we were comparing against a stable
	 * release, and cmp == 0, then this means an update in SVN about
	 * a "released" version, probably alpha/beta.
	 */

	if (
		cmp == 0 &&
		(delta_time(their_version.timestamp, target_version->timestamp) > 0
			|| their_version.build > target_version->build) &&
		target_version == &last_rel_version
	) {
		if (GNET_PROPERTY(version_debug) > 3)
			g_debug("VERSION is a SVN update of a release");

		if (version_build_cmp(&last_dev_version, &their_version) > 0) {
			if (GNET_PROPERTY(version_debug) > 3)
				g_debug("VERSION is less recent than latest dev we know");
			return TRUE;
		}
		target_version = &last_dev_version;
	}

	/*
	 * Their version is more recent, but is unstable -- only continue if
	 * our version is also unstable.
	 */

	if (cmp < 0 && their_version.tag == 'u' && our_version.tag != 'u')
		return TRUE;

	if (
		delta_time(their_version.timestamp, target_version->timestamp) < 0 ||
		their_version.build <= target_version->build
	)
		return TRUE;

	if (
		delta_time(their_version.timestamp, our_version.timestamp) == 0 &&
		their_version.build <= our_version.build
	)
		return TRUE;

	/*
	 * We found a more recent version than the last version seen.
	 */

	if (GNET_PROPERTY(version_debug) > 1)
		g_debug("more recent %s VERSION \"%s\"",
			target_version == &last_dev_version ? "dev" : "rel", str);

	*target_version = their_version;		/* struct copy */

	/*
	 * Signal new version to user.
	 *
	 * Unless they run a development version, don't signal development
	 * updates to them: they're probably not interested.
	 */

	version =  version_ext_str(&their_version_ext, FALSE);	/* No OS name */

	g_message("more recent %s version of gtk-gnutella: %s",
		target_version == &last_dev_version ? "development" : "released",
		version);

	if (target_version == &last_rel_version)
		version_new_found(version, TRUE);
	else if (our_version.tag == 'u')
		version_new_found(version, FALSE);

	return TRUE;
}
コード例 #3
0
ファイル: version.c プロジェクト: Eppo791906066/gtk-gnutella
/**
 * Parse gtk-gnutella's version number in User-Agent/Server string `str'
 * and extract relevant information into `ver'.
 *
 * @param str	the version string to be parsed
 * @param ver	the structure filled with parsed information
 * @param end	filled with a pointer to the first unparsed character
 *
 * @returns TRUE if we parsed a gtk-gnutella version correctly, FALSE if we
 * were not facing a gtk-gnutella version, or if we did not recognize it.
 */
static bool
version_parse(const char *str, version_t *ver, const char **end)
{
	const char *v;
	int error;

	/*
	 * Modern version numbers are formatted like this:
	 *
	 *    gtk-gnutella/0.85 (04/04/2002; X11; FreeBSD 4.6-STABLE i386)
	 *    gtk-gnutella/0.90u (24/06/2002; X11; Linux 2.4.18-pre7 i686)
	 *    gtk-gnutella/0.90b (24/06/2002; X11; Linux 2.4.18-2emi i686)
	 *    gtk-gnutella/0.90b2 (24/06/2002; X11; Linux 2.4.18-2emi i686)
	 *
	 * The letter after the version number is either 'u' for unstable, 'a'
	 * for alpha, 'b' for beta, or nothing for a stable release.  It can be
	 * followed by digits when present.
	 *
	 * In prevision for future possible extensions, we also parse
	 *
	 *    gtk-gnutella/0.90.1b2 (24/06/2002; X11; Linux 2.4.18-2emi i686)
	 *
	 * where the third number is the "patchlevel".
	 *
	 * Starting 2006-08-26, the user-agent string includes the SVN revision
	 * at the time of the build.  To be compatible with the servents out
	 * there, the version is included as an optional tag following the date.
	 *
	 *    gtk-gnutella/0.85 (04/04/2002; r3404; X11; FreeBSD 4.6-STABLE i386)
	 *
	 * However, we also start parsing the new format that we shall use when
	 * all current GTKG out there have expired:
	 *
	 *    gtk-gnutella/0.85-3404 (04/04/2002; X11; FreeBSD 4.6-STABLE i386)
	 *    gtk-gnutella/0.90b2-3404 (04/04/2002; X11; FreeBSD 4.6-STABLE i386)
	 *
	 * where the '-3404' introduces the build number.
	 *
	 * Since switching to git (2011-09-11), the SVN build is no longer present
	 * but rather the output of "git describe" is used to show any difference
	 * with the latest release tag.
	 *
	 * A release would be described as:
	 *
	 *    gtk-gnutella/0.97.1 (2011-09-11; GTK1; Linux i686)
	 *
	 * but any change on top of that would be seen as:
	 *
	 *    gtk-gnutella/0.97.1-24-g844b7 (2011-09-11; GTK1; Linux i686)
	 *
	 * to indicate that 24 commits were made after the release, and the commit
	 * ID is 844b7... (only enough hexadecimal digits are output to make the
	 * string unique at the time it was generated.
	 *
	 * If furthermore a build is done from a dirty git repository, the string
	 * "-dirty" is appended after the commit ID:
	 *
	 *    gtk-gnutella/0.97.1-24-g844b7-dirty (2011-09-11; GTK1; Linux i686)
	 */

	if (NULL == (v = is_strprefix(str, GTA_PRODUCT_NAME "/")))
		return FALSE;

	/*
	 * Parse "major.minor", followed by optional ".patchlevel".
	 */

	ver->major = parse_uint32(v, &v, 10, &error);
	if (error)
		return FALSE;

	if (*v++ != '.')
		return FALSE;

	ver->minor = parse_uint32(v, &v, 10, &error);
	if (error)
		return FALSE;

	if ('.' == *v) {
		v++;
		ver->patchlevel = parse_uint32(v, &v, 10, &error);
		if (error)
			return FALSE;
	} else
		ver->patchlevel = 0;

	/*
	 * Parse optional tag letter "x" followed by optional "taglevel".
	 */

	if (is_ascii_alpha(*v)) {
		ver->tag = *v++;
		if (is_ascii_digit(*v)) {
			ver->taglevel = parse_uint32(v, &v, 10, &error);
			if (error)
				return FALSE;
		} else
			ver->taglevel = 0;
	} else {
		ver->tag = '\0';
		ver->taglevel = 0;
	}

	/*
	 * Parse optional "-build" (legacy SVN) or "-change-bxxxxxxxx" (git
	 * version scheme) to be able to sort identical versions with distinct
	 * changes applied to them.
	 */

	if ('-' == *v) {
		v++;
		if (!is_strprefix(v, "dirty")) {
			ver->build = parse_uint32(v, &v, 10, &error);
			if (error)
				return FALSE;
		}
	} else
		ver->build = 0;

	if (end != NULL)
		*end = v;

	if (GNET_PROPERTY(version_debug) > 1)
		version_dump(str, ver, "#");

	return TRUE;
}