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; }
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; }
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; }
/** 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; }
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); }
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; }
int simpleStringCmp(const void * a, const void * b) { const char * first = *((const char **) a); const char * second = *((const char **) b); return rpmvercmp(first, second); }
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); }
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; }
int RpmBackEnd::verCmp(const std::string& ver1, const std::string& ver2) const { return rpmvercmp(ver1.c_str(), ver2.c_str()); }
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; }
int compare_versions (const char * a, const char *b) { return rpmvercmp (a, b); }
/** * 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; }