Exemple #1
0
int deps_match(const struct deps *deps, uint x, uint y) {
	uint f1, f2;
	const char *s1, *s2;
	int d;

	if (array_get(&deps->names, x) != array_get(&deps->names, y))
	       return 0;

	f1 = array_get(&deps->flags, x);
        f2 = array_get(&deps->flags, y);

	if (!f1 || !f2)
		return 1;

	d = array_get(&deps->epochs, x) - array_get(&deps->epochs, y);
	if (!d) {
		s1 = strings_get(deps->strings, array_get(&deps->vers, x)); 
		s2 = strings_get(deps->strings, array_get(&deps->vers, y)); 
		if (*s1 && *s2)
			d = rpmvercmp(s1, s2);
	}
	if (!d) {
		s1 = strings_get(deps->strings, array_get(&deps->rels, x)); 
		s2 = strings_get(deps->strings, array_get(&deps->rels, y)); 
		if (*s1 && *s2)
			d = rpmvercmp(s1, s2);
	}
	if ((!d && f1 & f2) ||
			(d > 0 && (f1 & RPMSENSE_LESS || f2 & RPMSENSE_GREATER)) ||
			(d < 0 && (f1 & RPMSENSE_GREATER || f2 & RPMSENSE_LESS)))
		return 1;
	return 0;
}
Exemple #2
0
static inline int rpmdsCompareEVR(const char *AEVR, uint32_t AFlags,
				  const char *BEVR, uint32_t BFlags,
				  int nopromote)
{
    const char *aE, *aV, *aR, *bE, *bV, *bR;
    char *aEVR = xstrdup(AEVR);
    char *bEVR = xstrdup(BEVR);
    int sense = 0;
    int result = 0;

    parseEVR(aEVR, &aE, &aV, &aR);
    parseEVR(bEVR, &bE, &bV, &bR);

    /* Compare {A,B} [epoch:]version[-release] */
    if (aE && *aE && bE && *bE)
	sense = rpmvercmp(aE, bE);
    else if (aE && *aE && atol(aE) > 0) {
	if (!nopromote) {
	    sense = 0;
	} else
	    sense = 1;
    } else if (bE && *bE && atol(bE) > 0)
	sense = -1;

    if (sense == 0) {
	sense = rpmvercmp(aV, bV);
	if (sense == 0) {
	    if (aR && *aR && bR && *bR) {
		sense = rpmvercmp(aR, bR);
	    } else {
		/* always matches if the side with no release has SENSE_EQUAL */
		if ((aR && *aR && (BFlags & RPMSENSE_EQUAL)) ||
		    (bR && *bR && (AFlags & RPMSENSE_EQUAL))) {
		    aEVR = _free(aEVR);
		    bEVR = _free(bEVR);
		    result = 1;
		    goto exit;
		}
	    }
	}
    }

    /* Detect overlap of {A,B} range. */
    if (sense < 0 && ((AFlags & RPMSENSE_GREATER) || (BFlags & RPMSENSE_LESS))) {
	result = 1;
    } else if (sense > 0 && ((AFlags & RPMSENSE_LESS) || (BFlags & RPMSENSE_GREATER))) {
	result = 1;
    } else if (sense == 0 &&
	(((AFlags & RPMSENSE_EQUAL) && (BFlags & RPMSENSE_EQUAL)) ||
	 ((AFlags & RPMSENSE_LESS) && (BFlags & RPMSENSE_LESS)) ||
	 ((AFlags & RPMSENSE_GREATER) && (BFlags & RPMSENSE_GREATER)))) {
	result = 1;
    }

exit:
    free(aEVR);
    free(bEVR);
    return result;
}
Exemple #3
0
static int compare_values(const char *str1, const char *str2)
{
    if (!str1 && !str2)
	return 0;
    else if (str1 && !str2)
	return 1;
    else if (!str1 && str2)
	return -1;
    return rpmvercmp(str1, str2);
}
int matchVersions(const char *version, uint32_t sense, const char *senseversion)
{
    int r = rpmvercmp(version, senseversion);

    if(r<0 && !(sense & RPMSENSE_LESS)) return 1;
    else if(r==0 && !(sense & RPMSENSE_EQUAL)) return 1;
    else if(r>0 && !(sense & RPMSENSE_GREATER)) return 1;

    return 0;
}
Exemple #5
0
/** Compare two version strings and determine which one is 'newer'.
 * Returns a value comparable to the way strcmp works. Returns 1
 * if a is newer than b, 0 if a and b are the same version, or -1
 * if b is newer than a.
 *
 * Different epoch values for version strings will override any further
 * comparison. If no epoch is provided, 0 is assumed.
 *
 * Keep in mind that the pkgrel is only compared if it is available
 * on both versions handed to this function. For example, comparing
 * 1.5-1 and 1.5 will yield 0; comparing 1.5-1 and 1.5-2 will yield
 * -1 as expected. This is mainly for supporting versioned dependencies
 * that do not include the pkgrel.
 */
int SYMEXPORT alpm_pkg_vercmp(const char *a, const char *b)
{
	char *full1, *full2;
	const char *epoch1, *ver1, *rel1;
	const char *epoch2, *ver2, *rel2;
	int ret;

	/* ensure our strings are not null */
	if(!a && !b) {
		return 0;
	} else if(!a) {
		return -1;
	} else if(!b) {
		return 1;
	}
	/* another quick shortcut- if full version specs are equal */
	if(strcmp(a, b) == 0) {
		return 0;
	}

	/* Parse both versions into [epoch:]version[-release] triplets. We probably
	 * don't need epoch and release to support all the same magic, but it is
	 * easier to just run it all through the same code. */
	full1 = strdup(a);
	full2 = strdup(b);

	/* parseEVR modifies passed in version, so have to dupe it first */
	parseEVR(full1, &epoch1, &ver1, &rel1);
	parseEVR(full2, &epoch2, &ver2, &rel2);

	ret = rpmvercmp(epoch1, epoch2);
	if(ret == 0) {
		ret = rpmvercmp(ver1, ver2);
		if(ret == 0 && rel1 && rel2) {
			ret = rpmvercmp(rel1, rel2);
		}
	}

	free(full1);
	free(full2);
	return ret;
}
Exemple #6
0
int rpmVersionCompare(Header first, Header second)
{
    /* Missing epoch becomes zero here, which is what we want */
    uint32_t epochOne = headerGetNumber(first, RPMTAG_EPOCH);
    uint32_t epochTwo = headerGetNumber(second, RPMTAG_EPOCH);
    int rc;

    if (epochOne < epochTwo)
	return -1;
    else if (epochOne > epochTwo)
	return 1;

    rc = rpmvercmp(headerGetString(first, RPMTAG_VERSION),
		   headerGetString(second, RPMTAG_VERSION));
    if (rc)
	return rc;

    return rpmvercmp(headerGetString(first, RPMTAG_RELEASE),
		     headerGetString(second, RPMTAG_RELEASE));
}
int main(int argc, char *argv[])
{
	char s1[255] = "";
	char s2[255] = "";
	int ret;
	
	if(argc > 1) {
		strncpy(s1, argv[1], 255);
	}
	if(argc > 2) {
		strncpy(s2, argv[2], 255);
	} else {
		printf("0\n");
		return(0);
	}
	
	ret = rpmvercmp(s1, s2);
	printf("%d\n", ret);
	return(ret);
}
Exemple #8
0
int rpmdsCompare(const rpmds A, const rpmds B)
{
    char *aEVR, *bEVR;
    const char *aE, *aV, *aR, *bE, *bV, *bR;
    int result;
    int sense;

    /* Different names don't overlap. */
    if (!rstreq(A->N[A->i], B->N[B->i])) {
	result = 0;
	goto exit;
    }

    /* XXX rpm prior to 3.0.2 did not always supply EVR and Flags. */
    if (!(A->EVR && A->Flags && B->EVR && B->Flags)) {
	result = 1;
	goto exit;
    }

    /* Same name. If either A or B is an existence test, always overlap. */
    if (!((A->Flags[A->i] & RPMSENSE_SENSEMASK) && (B->Flags[B->i] & RPMSENSE_SENSEMASK))) {
	result = 1;
	goto exit;
    }

    /* If either EVR is non-existent or empty, always overlap. */
    if (!(A->EVR[A->i] && *A->EVR[A->i] && B->EVR[B->i] && *B->EVR[B->i])) {
	result = 1;
	goto exit;
    }

    /* Both AEVR and BEVR exist. */
    aEVR = xstrdup(A->EVR[A->i]);
    parseEVR(aEVR, &aE, &aV, &aR);
    bEVR = xstrdup(B->EVR[B->i]);
    parseEVR(bEVR, &bE, &bV, &bR);

    /* Compare {A,B} [epoch:]version[-release] */
    sense = 0;
    if (aE && *aE && bE && *bE)
	sense = rpmvercmp(aE, bE);
    else if (aE && *aE && atol(aE) > 0) {
	if (!B->nopromote) {
	    sense = 0;
	} else
	    sense = 1;
    } else if (bE && *bE && atol(bE) > 0)
	sense = -1;

    if (sense == 0) {
	sense = rpmvercmp(aV, bV);
	if (sense == 0) {
	    if (aR && *aR && bR && *bR) {
		sense = rpmvercmp(aR, bR);
	    } else {
		/* always matches if the side with no release has SENSE_EQUAL */
		if ((aR && *aR && (B->Flags[B->i] & RPMSENSE_EQUAL)) ||
		    (bR && *bR && (A->Flags[A->i] & RPMSENSE_EQUAL))) {
		    aEVR = _free(aEVR);
		    bEVR = _free(bEVR);
		    result = 1;
		    goto exit;
		}
	    }
	}
    }
    aEVR = _free(aEVR);
    bEVR = _free(bEVR);

    /* Detect overlap of {A,B} range. */
    result = 0;
    if (sense < 0 && ((A->Flags[A->i] & RPMSENSE_GREATER) || (B->Flags[B->i] & RPMSENSE_LESS))) {
	result = 1;
    } else if (sense > 0 && ((A->Flags[A->i] & RPMSENSE_LESS) || (B->Flags[B->i] & RPMSENSE_GREATER))) {
	result = 1;
    } else if (sense == 0 &&
	(((A->Flags[A->i] & RPMSENSE_EQUAL) && (B->Flags[B->i] & RPMSENSE_EQUAL)) ||
	 ((A->Flags[A->i] & RPMSENSE_LESS) && (B->Flags[B->i] & RPMSENSE_LESS)) ||
	 ((A->Flags[A->i] & RPMSENSE_GREATER) && (B->Flags[B->i] & RPMSENSE_GREATER)))) {
	result = 1;
    }

exit:
    return result;
}
Exemple #9
0
int simpleStringCmp(const void * a, const void * b) {
    const char * first = *((const char **) a);
    const char * second = *((const char **) b);

    return rpmvercmp(first, second);
}
Exemple #10
0
int main(int argc, char **argv)
{
    abrt_init(argv);
    enum {
        OPT_v = 1 << 0,
        OPT_d = 1 << 1,
        OPT_g = 1 << 2,
        OPT_b = 1 << 3,
        OPT_u = 1 << 4,
        OPT_r = 1 << 5,
    };

    const char *bugs = NULL, *release = NULL, *dump_dir_path = ".";
    /* Keep enum above and order of options below in sync! */
    struct options program_options[] = {
        OPT__VERBOSE(&g_verbose),
        OPT__DUMP_DIR(&dump_dir_path),
        OPT_GROUP(""),
        OPT_STRING('b', "bugs", &bugs, "ID1[,ID2,...]" , _("List of bug ids")),
        OPT_STRING('u', "url", &bodhi_url, "URL", _("Specify a bodhi server url")),
        OPT_OPTSTRING('r', "release", &release, "RELEASE", _("Specify a release")),
        OPT_END()
    };

    const char *program_usage_string = _(
        "& [-v] [-r[RELEASE]] (-b ID1[,ID2,...] | PKG-NAME) [PKG-NAME]... \n"
        "\n"
        "Search for updates on bodhi server"
    );

    unsigned opts =  parse_opts(argc, argv, program_options, program_usage_string);

    if (!bugs && !argv[optind])
        show_usage_and_die(program_usage_string, program_options);

    struct strbuf *query = strbuf_new();
    if (bugs)
        query = strbuf_append_strf(query, "bugs=%s&", bugs);

    if (opts & OPT_r)
    {
        if (release)
        {
            query = strbuf_append_strf(query, "release=%s&", release);
        }
        else
        {
            struct dump_dir *dd = dd_opendir(dump_dir_path, DD_OPEN_READONLY);
            if (!dd)
                xfunc_die();

            problem_data_t *problem_data = create_problem_data_from_dump_dir(dd);
            dd_close(dd);
            if (!problem_data)
                xfunc_die(); /* create_problem_data_for_reporting already emitted error msg */

            char *product, *version;
            map_string_t *osinfo = new_map_string();
            problem_data_get_osinfo(problem_data, osinfo);
            parse_osinfo_for_rhts(osinfo, &product, &version);
            query = strbuf_append_strf(query, "release=f%s&", version);
            free(product);
            free(version);
            free_map_string(osinfo);
        }
    }

    if (argv[optind])
    {
        char *escaped = g_uri_escape_string(argv[optind], NULL, 0);
        query = strbuf_append_strf(query, "package=%s&", escaped);
        free(escaped);
    }

    if (query->buf[query->len - 1] == '&')
        query->buf[query->len - 1] = '\0';

    log(_("Searching for updates"));
    GHashTable *update_hash_tbl = bodhi_query_list(query->buf, release);
    strbuf_free(query);

    if (!update_hash_tbl || !g_hash_table_size(update_hash_tbl))
    {
        log(_("No updates for this package found"));
        /*if (update_hash_tbl) g_hash_table_unref(update_hash_tbl);*/
        return 0;
    }

    GHashTableIter iter;
    char *name;
    struct bodhi *b;
    struct strbuf *q = strbuf_new();
    g_hash_table_iter_init(&iter, update_hash_tbl);
    while (g_hash_table_iter_next(&iter, (void **) &name, (void **) &b))
    {
        char *installed_pkg_nvr = rpm_get_nvr_by_pkg_name(name);
        if (installed_pkg_nvr && rpmvercmp(installed_pkg_nvr, b->nvr) >= 0)
        {
            log_info("Update %s is older or same as local version %s, skipping", b->nvr, installed_pkg_nvr);
            free(installed_pkg_nvr);
            continue;
        }
        free(installed_pkg_nvr);

        strbuf_append_strf(q, " %s", b->nvr);
    }

    /*g_hash_table_unref(update_hash_tbl);*/

    if (!q->len)
    {
        /*strbuf_free(q);*/
        log(_("Local version of the package is newer than available updates"));
        return 0;
    }

    /* Message is split into text and command in order to make
     * translator's job easier
     */

    /* We suggest the command which is most likely to exist on user's system,
     * and which is familiar to the largest population of users.
     * There are other tools (pkcon et al) which might be somewhat more
     * convenient (for example, they might be usable from non-root), but they
     * might be not present on the system, may evolve or be superseded,
     * while yum is unlikely to do so.
     */
    strbuf_prepend_str(q, "yum update --enablerepo=fedora --enablerepo=updates-testing");

    char *msg = xasprintf(_("An update exists which might fix your problem. "
                "You can install it by running: %s. "
                "Do you want to continue with reporting the bug?"),
                q->buf
    );
    /*strbuf_free(q);*/

    return !ask_yes_no(msg);
}
Exemple #11
0
static GHashTable *bodhi_parse_json(json_object *json, const char *release)
{

    int num_items = 0;
    bodhi_read_value(json, "num_items", &num_items, BODHI_READ_INT);
    if (num_items <= 0)
        return NULL;

    json_object *updates = NULL;
    bodhi_read_value(json, "updates", &updates, BODHI_READ_JSON_OBJ);
    if (!updates)
        return NULL;

    int updates_len = json_object_array_length(updates);

    GHashTable *bodhi_table = g_hash_table_new_full(g_str_hash, g_str_equal, free,
                                                    (GDestroyNotify) free_bodhi_item);
    for (int i = 0; i < updates_len; ++i)
    {
        json_object *updates_item = json_object_array_get_idx(updates, i);

        /* some of item are null */
        if (!updates_item)
            continue;

        json_object *builds_item = NULL;
        bodhi_read_value(updates_item, "builds", &builds_item, BODHI_READ_JSON_OBJ);
        if (!builds_item) /* broken json */
            continue;

        int karma, unstable_karma;
        bodhi_read_value(updates_item, "karma", &karma, BODHI_READ_INT);
        bodhi_read_value(updates_item, "unstable_karma", &unstable_karma, BODHI_READ_INT);
        if (karma <= unstable_karma)
            continue;

        struct bodhi *b = NULL;
        int builds_len = json_object_array_length(builds_item);
        for (int k = 0; k < builds_len; ++k)
        {
            b = xzalloc(sizeof(struct bodhi));

            char *name = NULL;
            json_object *build = json_object_array_get_idx(builds_item, k);

            bodhi_read_value(build, "nvr", &b->nvr, BODHI_READ_STR);

            json_object *package = NULL;
            bodhi_read_value(build, "package", &package, BODHI_READ_JSON_OBJ);
            bodhi_read_value(package, "name", &name, BODHI_READ_STR);

            struct bodhi *bodhi_tbl_item = g_hash_table_lookup(bodhi_table, name);
            if (bodhi_tbl_item && rpmvercmp(bodhi_tbl_item->nvr, b->nvr) > 0)
            {
                free_bodhi_item(b);
                continue;
            }
            g_hash_table_replace(bodhi_table, name, b);
        }

#if 0
        bodhi_read_value(updates_item, "date_pushed", &b->date_pushed, BODHI_READ_STR);
        bodhi_read_value(updates_item, "status", &b->status, BODHI_READ_STR);

        json_object *release_item = NULL;
        bodhi_read_value(updates_item, "release", &release_item, BODHI_READ_JSON_OBJ);
        if (release_item)
            bodhi_read_value(release_item, "dist_tag", &b->dist_tag, BODHI_READ_STR);

        json_object *bugs = NULL;
        bodhi_read_value(updates_item, "bugs", &release_item, BODHI_READ_JSON_OBJ);
        if (bugs)
        {
            for (int j = 0; j < json_object_array_length(bugs); ++j)
            {
                int *bz_id = xmalloc(sizeof(int));
                json_object *bug_item = json_object_array_get_idx(bugs, j);
                bodhi_read_value(bug_item, "bz_id", bz_id, BODHI_READ_INT);
                b->bz_ids = g_list_append(b->bz_ids, bz_id);
            }
        }
#endif
    }

    return bodhi_table;
}
Exemple #12
0
int RpmBackEnd::verCmp(const std::string& ver1, const std::string& ver2) const
{
  return rpmvercmp(ver1.c_str(), ver2.c_str());
}
Exemple #13
0
static inline int
cr_compare_dependency(const char *dep1, const char *dep2)
{
    /* Compares two dependency by name
     * NOTE: The function assume first parts must be same!
     * libc.so.6() < libc.so.6(GLIBC_2.3.4)(64 bit) < libc.so.6(GLIBC_2.4)
     * Return values: 0 - same; 1 - first is bigger; 2 - second is bigger,
     * -1 - error
     */
    int ret1;
    char *ver1, *ver2, *ver1_e, *ver2_e;

    if (dep1 == dep2) return 0;

    ver1 = strchr(dep1, '('); // libc.so.6(...
    ver2 = strchr(dep2, '('); //    verX  ^

    // There is no '('
    if (!ver1 && !ver2) return 0;
    if (!ver1) return 2;
    if (!ver2) return 1;

    ver1_e = strchr(ver1, ')'); // libc.so.6(xxx)...
    ver2_e = strchr(ver2, ')'); //       verX_e ^

    // If there is no ')'
    if (!ver1_e && !ver2_e) return -1;
    if (!ver1_e) return 2;
    if (!ver2_e) return 1;

    // Go to char next to '('
    ver1++; // libc.so.6(...
    ver2++; //      verX ^

    // If parentheses have no content - libc.so.6()... == libc.so.6()...
    if (ver1 == ver1_e && ver2 == ver2_e) return 0;
    if (ver1 == ver1_e) return 2;
    if (ver2 == ver2_e) return 1;

    // Go to first number
    for (; *ver1 && (*ver1 < '0' || *ver1 > '9'); ver1++); // libc.so.6(GLIBC_2...
    for (; *ver2 && (*ver2 < '0' || *ver2 > '9'); ver2++); //            verX ^

    // Too far
    // libc.so.6(xxx)(64bit)
    //           verX ^
    if (ver1 > ver1_e && ver2 > ver2_e) return 0;
    if (ver1 > ver1_e) return 2;
    if (ver2 > ver2_e) return 1;

/*  XXX: This piece of code could be removed in future 
    // Check if version is really version and not an architecture
    // case: libc.so.6(64bit) = 64 is not a version!
    ret1 = strncmp(ver1, "64bit", 5);
    ret2 = strncmp(ver2, "64bit", 5);
    if (!ret1 && !ret2) return 0;
    if (!ret1) return 2;
    if (!ret2) return 1;
*/
    // Get version string
    ver1 = g_strndup(ver1, (ver1_e - ver1));
    ver2 = g_strndup(ver2, (ver2_e - ver2));

    // Compare versions
    ret1 = rpmvercmp(ver1, ver2);
    if (ret1 == -1) ret1 = 2;

    g_free(ver1);
    g_free(ver2);
    return ret1;
}
Exemple #14
0
int
compare_versions (const char * a, const char *b)
{
  return rpmvercmp (a, b);
}
Exemple #15
0
/**
 * zif_compare_evr_full:
 * @a: The first version string, or %NULL
 * @b: The second version string, or %NULL
 * @compare_mode: the way the versions are compared
 *
 * Compare two [epoch:]version[-release] strings
 *
 * Return value: 1 for a>b, 0 for a==b, -1 for b>a
 *
 * Since: 0.2.1
 **/
gint
zif_compare_evr_full (const gchar *a, const gchar *b,
		      ZifPackageCompareMode compare_mode)
{
	gint val = 0;
	gchar a_tmp[128]; /* 128 bytes should be enough for anybody, heh */
	gchar b_tmp[128];
	const gchar *ae, *av, *ar, *ad;
	const gchar *be, *bv, *br, *bd;

	/* exactly the same, optimise */
	if (g_strcmp0 (a, b) == 0)
		goto out;

	/* deal with one evr being NULL and the other a value */
	if (a != NULL && b == NULL) {
		val = 1;
		goto out;
	}
	if (a == NULL && b != NULL) {
		val = -1;
		goto out;
	}

	/* copy */
	g_strlcpy (a_tmp, a, 128);
	g_strlcpy (b_tmp, b, 128);

	/* split */
	zif_package_convert_evr_full (a_tmp, &ae, &av, &ar, &ad);
	zif_package_convert_evr_full (b_tmp, &be, &bv, &br, &bd);

	/* compare distro */
	if (ad != NULL &&
	    bd != NULL &&
	    compare_mode == ZIF_PACKAGE_COMPARE_MODE_DISTRO) {
		val = rpmvercmp (ad, bd);
		if (val != 0)
			goto out;
	}

	/* compare epoch */
	if (ae != NULL && be != NULL) {
		val = rpmvercmp (ae, be);
		if (val != 0)
			goto out;
	} else if (ae != NULL && atoi (ae) > 0) {
		val = 1;
		goto out;
	} else if (be != NULL && atoi (be) > 0) {
		val = -1;
		goto out;
	}

	/* compare version */
	val = rpmvercmp (av, bv);
	if (val != 0)
		goto out;

	/* compare release */
	if (ar != NULL && br != NULL) {
		val = rpmvercmp (ar, br);
		if (val != 0)
			goto out;
	}

	/* compare distro */
	if (ad != NULL && bd != NULL) {
		val = rpmvercmp (ad, bd);
		if (val != 0)
			goto out;
	}
out:
	return val;
}