int main(int argc, char *argv[]) { int cmprc; const char *v1, *v2; EVR_t evr1, evr2; if (argc < 3) { printf("Usage: rpmvercmp VERSION1 VERSION2\n"); exit(EXIT_SUCCESS); } if (argc == 3) { v1 = argv[1]; v2 = argv[2]; } else { printf("Usage: rpmvercmp VERSION1 VERSION2\n"); exit(1); } if (rpmReadConfigFiles(NULL, NULL) < 0) { fprintf(stderr, "Failed to read configuration files\n"); exit(2); } evr1 = malloc(sizeof(struct EVR_s)); evr2 = malloc(sizeof(struct EVR_s)); #ifdef HAVE_RPM_5 rpmEVRparse(v1, evr1); rpmEVRparse(v2, evr2); #else parse(v1, evr1); parse(v2, evr2); #endif cmprc = rpmEVRcompare(evr1, evr2); printf("%s %s %s\n", v1, cmprc == 0 ? "==" : cmprc > 0 ? ">" : "<", v2); if (cmprc < 0) cmprc = 2; free((char *)evr1->str); free((char *)evr2->str); free(evr1); free(evr2); exit(cmprc); }
static void parse(const char *evrstr, EVR_t evr) { rpmEVRparse(evrstr, evr); if (evr->E == NULL) { evr->E = "0"; evr->Elong = 0; } if (evr->R == NULL) evr->R = "0"; }
int dpkgEVRparse(const char * evrstr, EVR_t evr) { return rpmEVRparse(evrstr, evr); }
int main(int argc, char *const argv[]) { poptContext optCon = rpmioInit(argc, argv, optionsTable); ARGV_t av; int ac; rpmdict dict; EVR_t evr = (EVR_t) xcalloc(1, sizeof(*evr)); const char * arg; int rc = 0; int xx; int i; if ((progname = strrchr(argv[0], '/')) != NULL) progname++; else progname = argv[0]; av = NULL; (void) argvAppend(&av, poptGetArgs(optCon)); ac = argvCount(av); if (ac == 0 || !strcmp(*av, "-")) { av = NULL; xx = argvFgets(&av, NULL); ac = argvCount(av); } dict = rpmdictCreate(); if (av != NULL) for (i = 0; (arg = av[i]) != NULL; i++) { if (*arg == '\0') /* Skip cruft */ continue; s.total++; if (nofiles && *arg == '/') { /* Skip file paths. */ s.files++; continue; } if (noKdigests && isKdigest(arg)) { /* Skip kernel MD5/SHA1. */ s.Kdigest++; continue; } if (noOdigests && isOdigest(arg)) { /* Skip OCAML EVR strings. */ s.Odigest++; continue; } /* Split E:V-R into components. */ xx = rpmEVRparse(arg, evr); if (evr->F[RPMEVR_E] == NULL) { evr->F[RPMEVR_E] = "0"; s.Emiss++; } if (evr->F[RPMEVR_R] == NULL) { evr->F[RPMEVR_R] = ""; s.Rmiss++; } rpmdictAdd(dict, evr->F[RPMEVR_E]); rpmdictAdd(dict, evr->F[RPMEVR_V]); rpmdictAdd(dict, evr->F[RPMEVR_R]); if (__debug) fprintf(stderr, "%5d: %s => %s:%s-%s\n", s.total, arg, evr->F[RPMEVR_E], evr->F[RPMEVR_V], evr->F[RPMEVR_R]); evr->str = _free(evr->str); } (void) argvSort(dict->av,(int (*)(const char **, const char **))rpmdictCmp); /* Compute size of string & uuid store. */ if (av != NULL) for (i = 0; av[i] != NULL; i++) { s.strnb += sizeof(*av) + strlen(av[i]) + 1; s.uuidnb += 64/8; } s.strnb += sizeof(*av) + 1; /* Compute size of dictionary store. */ for (i = 0; dict->av[i] != NULL; i++) { s.dictnb += sizeof(*dict->av) + strlen(dict->av[i]) + 1; } s.dictnb += sizeof(*dict->av) + 1; fprintf(stderr, "total:%u files:%u Kdigest:%u Odigest:%u Emiss:%u Rmiss:%u dictlen:%u strnb:%u dictnb:%u uuidnb:%u\n", s.total, s.files, s.Kdigest, s.Odigest, s.Emiss, s.Rmiss, argvCount(dict->av), (unsigned)s.strnb, (unsigned)s.dictnb, (unsigned)s.uuidnb); if (__debug) argvPrint("E:V-R dictionary", dict->av, NULL); evr = _free(evr); dict = rpmdictFree(dict); av = argvFree(av); optCon = rpmioFini(optCon); return rc; }
int addReqProv(/*@unused@*/ Spec spec, Header h, /*@unused@*/ rpmTag tagN, const char * N, const char * EVR, rpmsenseFlags Flags, rpmuint32_t index) { HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he)); const char ** names; rpmTag nametag = 0; rpmTag versiontag = 0; rpmTag flagtag = 0; rpmTag indextag = 0; int len; rpmsenseFlags extra = RPMSENSE_ANY; int xx; if (Flags & RPMSENSE_PROVIDES) { nametag = RPMTAG_PROVIDENAME; versiontag = RPMTAG_PROVIDEVERSION; flagtag = RPMTAG_PROVIDEFLAGS; extra = Flags & RPMSENSE_FIND_PROVIDES; } else if (Flags & RPMSENSE_OBSOLETES) { nametag = RPMTAG_OBSOLETENAME; versiontag = RPMTAG_OBSOLETEVERSION; flagtag = RPMTAG_OBSOLETEFLAGS; } else if (Flags & RPMSENSE_CONFLICTS) { nametag = RPMTAG_CONFLICTNAME; versiontag = RPMTAG_CONFLICTVERSION; flagtag = RPMTAG_CONFLICTFLAGS; } else if (Flags & RPMSENSE_TRIGGER) { nametag = RPMTAG_TRIGGERNAME; versiontag = RPMTAG_TRIGGERVERSION; flagtag = RPMTAG_TRIGGERFLAGS; indextag = RPMTAG_TRIGGERINDEX; extra = Flags & RPMSENSE_TRIGGER; } else { nametag = RPMTAG_REQUIRENAME; versiontag = RPMTAG_REQUIREVERSION; flagtag = RPMTAG_REQUIREFLAGS; extra = Flags & _ALL_REQUIRES_MASK; } Flags = (Flags & RPMSENSE_SENSEMASK) | extra; if (EVR == NULL) EVR = ""; #if defined(RPM_VENDOR_MANDRIVA) /* Check that provide isn't duplicate of package */ else if (nametag == RPMTAG_PROVIDENAME) { const char *NEVR; size_t len; int duplicate; len = strlen(N); NEVR = headerSprintf(h, "%{NAME}-%|EPOCH?{%{EPOCH}:}|%{VERSION}-%{RELEASE}", NULL, NULL, NULL); duplicate = !strncmp(NEVR, N, len) && !strcmp(NEVR+len+1, EVR); _free(NEVR); if (duplicate) return 0; } #endif /* Check for duplicate dependencies. */ he->tag = nametag; xx = headerGet(h, he, 0); names = he->p.argv; len = he->c; if (xx) { const char ** versions = NULL; rpmuint32_t * flags = NULL; rpmuint32_t * indexes = NULL; int duplicate = 0; if (flagtag) { he->tag = versiontag; xx = headerGet(h, he, 0); versions = he->p.argv; he->tag = flagtag; xx = headerGet(h, he, 0); flags = he->p.ui32p; } if (indextag) { he->tag = indextag; xx = headerGet(h, he, 0); indexes = he->p.ui32p; } while (len > 0) { len--; if (strcmp(names[len], N)) continue; #if defined(RPM_VENDOR_MANDRIVA) /* filter-overlapping-dependencies */ /* XXX: Potential drawbacks? Need to study & discuess this one a * bit further, leaving under #ifdef for now... * TODO: auto-generated deps too */ if (flagtag && versions != NULL) { int overlap; if(*EVR && !*versions[len]) { overlap = 1; flags[len] = Flags; he->tag = flagtag; he->t = RPM_UINT32_TYPE; he->p.argv = (void *) &Flags; xx = headerMod(h, he, 0); } else { EVR_t lEVR = rpmEVRnew(RPMSENSE_ANY, 0), rEVR = rpmEVRnew(RPMSENSE_ANY, 0); rpmEVRparse(EVR, lEVR); rpmEVRparse(versions[len], rEVR); lEVR->Flags = Flags | RPMSENSE_EQUAL; rEVR->Flags = flags[len] | RPMSENSE_EQUAL; overlap = rpmEVRoverlap(lEVR, rEVR); if (!overlap) if (rpmEVRoverlap(rEVR, lEVR)) duplicate = 1; lEVR = rpmEVRfree(lEVR); rEVR = rpmEVRfree(rEVR); } if (overlap) { versions[len] = EVR; he->tag = versiontag; he->t = RPM_STRING_ARRAY_TYPE; he->p.argv = versions; xx = headerMod(h, he, 0); } else continue; } #else if (flagtag && versions != NULL && (strcmp(versions[len], EVR) || (rpmsenseFlags)flags[len] != Flags)) continue; #endif if (indextag && indexes != NULL && indexes[len] != index) continue; /* This is a duplicate dependency. */ duplicate = 1; break; } /*@-usereleased@*/ names = _free(names); versions = _free(versions); flags = _free(flags); indexes = _free(indexes); /*@=usereleased@*/ if (duplicate) return 0; } /* Add this dependency. */ he->tag = nametag; he->t = RPM_STRING_ARRAY_TYPE; he->p.argv = &N; he->c = 1; he->append = 1; xx = headerPut(h, he, 0); he->append = 0; if (flagtag) { he->tag = versiontag; he->t = RPM_STRING_ARRAY_TYPE; he->p.argv = &EVR; he->c = 1; he->append = 1; xx = headerPut(h, he, 0); he->append = 0; he->tag = flagtag; he->t = RPM_UINT32_TYPE; he->p.ui32p = (void *) &Flags; he->c = 1; he->append = 1; xx = headerPut(h, he, 0); he->append = 0; } if (indextag) { he->tag = indextag; he->t = RPM_UINT32_TYPE; he->p.ui32p = &index; he->c = 1; he->append = 1; xx = headerPut(h, he, 0); he->append = 0; } return 0; }