From 0996af64d6d7a6900b78a835c05945a86e589a28 Mon Sep 17 00:00:00 2001 From: Michael Schroeder Date: Thu, 16 Jul 2009 14:08:55 +0200 Subject: [PATCH] - bring argument parsing up-to-speed, now supports globs, relations - fix repo.c filelist handling --- examples/solv.c | 598 +++++++++++++++++++++++++++++++++++++++++--------------- src/repo.c | 20 +- 2 files changed, 456 insertions(+), 162 deletions(-) diff --git a/examples/solv.c b/examples/solv.c index e04221c..e86d3ee 100644 --- a/examples/solv.c +++ b/examples/solv.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -30,6 +31,7 @@ #include "poolarch.h" #include "repo.h" #include "evr.h" +#include "policy.h" #include "util.h" #include "solver.h" #include "solverdebug.h" @@ -90,17 +92,23 @@ yum_substitute(Pool *pool, char *line) static char *releaseevr; if (!releaseevr) { - FILE *fp; - char buf[1024], *bp; - - fp = popen("rpm --nodigest --nosignature -q --qf '%{VERSION}\n' --whatprovides redhat-release", "r"); - fread(buf, 1, sizeof(buf), fp); - fclose(fp); - bp = buf; - while (*bp != ' ' && *bp != '\t' && *bp != '\n') - bp++; - *bp = 0; - releaseevr = strdup(buf); + Queue q; + + queue_init(&q); + rpm_installedrpmdbids(0, "Providename", "redhat-release", &q); + if (q.count) + { + void *handle, *state = 0; + char *p; + handle = rpm_byrpmdbid(q.elements[0], 0, &state); + releaseevr = rpm_query(handle, SOLVABLE_EVR); + rpm_byrpmdbid(0, 0, &state); + if (p = strchr(releaseevr, '-')) + *p = 0; + } + queue_free(&q); + if (!releaseevr) + releaseevr = strdup("?"); } *p2 = 0; p = pool_tmpjoin(pool, line, releaseevr, p2 + 11); @@ -270,16 +278,20 @@ read_repoinfos(Pool *pool, const char *reposdir, int *nrepoinfosp) return repoinfos; } -static ssize_t -cookie_gzread(void *cookie, char *buf, size_t nbytes) -{ - return gzread((gzFile *)cookie, buf, nbytes); -} - -static int -cookie_gzclose(void *cookie) +void +free_repoinfos(struct repoinfo *repoinfos, int nrepoinfos) { - return gzclose((gzFile *)cookie); + int i; + for (i = 0; i < nrepoinfos; i++) + { + struct repoinfo *cinfo = repoinfos + i; + sat_free(cinfo->name); + sat_free(cinfo->alias); + sat_free(cinfo->path); + sat_free(cinfo->metalink); + sat_free(cinfo->baseurl); + } + sat_free(repoinfos); } static inline int @@ -351,6 +363,18 @@ findmetalinkurl(FILE *fp) return 0; } +static ssize_t +cookie_gzread(void *cookie, char *buf, size_t nbytes) +{ + return gzread((gzFile *)cookie, buf, nbytes); +} + +static int +cookie_gzclose(void *cookie) +{ + return gzclose((gzFile *)cookie); +} + FILE * curlfopen(struct repoinfo *cinfo, const char *file, int uncompress, const unsigned char *chksum, Id chksumtype) { @@ -436,7 +460,7 @@ curlfopen(struct repoinfo *cinfo, const char *file, int uncompress, const unsign return fdopen(fd, "r"); } -void +static void cleanupgpg(char *gpgdir) { char cmd[256]; @@ -583,7 +607,7 @@ usecachedrepo(Repo *repo, const char *repoext, unsigned char *cookie) FILE *fp; unsigned char mycookie[32]; struct repoinfo *cinfo; - int flags = 0; + int flags; cinfo = repo->appdata; if (!(fp = fopen(calccachepath(repo, repoext), "r"))) @@ -599,18 +623,21 @@ usecachedrepo(Repo *repo, const char *repoext, unsigned char *cookie) return 0; } rewind(fp); - if (repoext && !strcmp(repoext, "DL")) + + flags = 0; + if (repoext) flags = REPO_USE_LOADING|REPO_EXTEND_SOLVABLES; - else if (repoext) - flags = REPO_USE_LOADING|REPO_LOCALPOOL|REPO_EXTEND_SOLVABLES; + if (repoext && strcmp(repoext, "DL") != 0) + flags |= REPO_LOCALPOOL; /* no local pool for DL so that we can compare IDs */ if (repo_add_solv_flags(repo, fp, flags)) { fclose(fp); return 0; } - if (!repoext && cinfo) + if (cinfo && !repoext) { + /* set the checksum so that we can use it with the stub loads */ struct stat stb; if (!fstat(fileno(fp), &stb)) calc_checksum_stat(&stb, REPOKEY_TYPE_SHA256, cinfo->extcookie); @@ -619,11 +646,12 @@ usecachedrepo(Repo *repo, const char *repoext, unsigned char *cookie) return 1; } -int +static int myrepodatafilter(Repo *repo, Repokey *key, void *kfdata) { Repodata *data = kfdata; + /* XXX: special repodata selection hack */ if (key->name == 1 && key->size != data - repo->repodata) return -1; if (key->storage == KEY_STORAGE_SOLVABLE) @@ -631,7 +659,7 @@ myrepodatafilter(Repo *repo, Repokey *key, void *kfdata) return repo_write_stdkeyfilter(repo, key, kfdata); } -static void +void writecachedrepo(Repo *repo, Repodata *info, const char *repoext, unsigned char *cookie) { Id *addedfileprovides = 0; @@ -694,6 +722,7 @@ writecachedrepo(Repo *repo, Repodata *info, const char *repoext, unsigned char * } if (!repoext && cinfo) { + /* set the checksum so that we can use it with the stub loads */ struct stat stb; if (!stat(tmpl, &stb)) calc_checksum_stat(&stb, REPOKEY_TYPE_SHA256, cinfo->extcookie); @@ -703,6 +732,7 @@ writecachedrepo(Repo *repo, Repodata *info, const char *repoext, unsigned char * free(tmpl); } + static Pool * read_sigs() { @@ -712,12 +742,8 @@ read_sigs() return sigpool; } -static inline int -iscompressed(const char *name) -{ - int l = strlen(name); - return l > 3 && !strcmp(name + l - 3, ".gz") ? 1 : 0; -} + +/* repomd helpers */ static inline const char * repomd_find(Repo *repo, const char *what, const unsigned char **chksump, Id *chksumtypep) @@ -781,14 +807,6 @@ repomd_add_ext(Repo *repo, Repodata *data, const char *what) { repodata_add_idarray(data, handle, REPOSITORY_KEYS, REPOSITORY_DELTAINFO); repodata_add_idarray(data, handle, REPOSITORY_KEYS, REPOKEY_TYPE_FLEXARRAY); - repodata_add_idarray(data, handle, REPOSITORY_KEYS, DELTA_PACKAGE_NAME); - repodata_add_idarray(data, handle, REPOSITORY_KEYS, REPOKEY_TYPE_ID); - repodata_add_idarray(data, handle, REPOSITORY_KEYS, DELTA_PACKAGE_EVR); - repodata_add_idarray(data, handle, REPOSITORY_KEYS, REPOKEY_TYPE_ID); - repodata_add_idarray(data, handle, REPOSITORY_KEYS, DELTA_PACKAGE_ARCH); - repodata_add_idarray(data, handle, REPOSITORY_KEYS, REPOKEY_TYPE_ID); - repodata_add_idarray(data, handle, REPOSITORY_KEYS, DELTA_BASE_EVR); - repodata_add_idarray(data, handle, REPOSITORY_KEYS, REPOKEY_TYPE_ID); } if (!strcmp(what, "filelists")) { @@ -800,6 +818,9 @@ repomd_add_ext(Repo *repo, Repodata *data, const char *what) return 1; } + +/* susetags helpers */ + static inline const char * susetags_find(Repo *repo, const char *what, const unsigned char **chksump, Id *chksumtypep) { @@ -827,6 +848,76 @@ susetags_find(Repo *repo, const char *what, const unsigned char **chksump, Id *c return filename; } +static Id susetags_langtags[] = { + SOLVABLE_SUMMARY, REPOKEY_TYPE_STR, + SOLVABLE_DESCRIPTION, REPOKEY_TYPE_STR, + SOLVABLE_EULA, REPOKEY_TYPE_STR, + SOLVABLE_MESSAGEINS, REPOKEY_TYPE_STR, + SOLVABLE_MESSAGEDEL, REPOKEY_TYPE_STR, + SOLVABLE_CATEGORY, REPOKEY_TYPE_ID, + 0, 0 +}; + +void +susetags_add_ext(Repo *repo, Repodata *data) +{ + Pool *pool = repo->pool; + Dataiterator di; + char ext[3]; + Id handle, filechksumtype; + const unsigned char *filechksum; + int i; + + dataiterator_init(&di, pool, repo, SOLVID_META, SUSETAGS_FILE_NAME, 0, 0); + dataiterator_prepend_keyname(&di, SUSETAGS_FILE); + while (dataiterator_step(&di)) + { + if (strncmp(di.kv.str, "packages.", 9) != 0) + continue; + if (!di.kv.str[9] || !di.kv.str[10] || (di.kv.str[11] && di.kv.str[11] != '.')) + continue; + ext[0] = di.kv.str[9]; + ext[1] = di.kv.str[10]; + ext[2] = 0; + if (!susetags_find(repo, di.kv.str, &filechksum, &filechksumtype)) + continue; + handle = repodata_new_handle(data); + repodata_set_str(data, handle, SUSETAGS_FILE_NAME, di.kv.str); + if (filechksumtype) + repodata_set_bin_checksum(data, handle, SUSETAGS_FILE_CHECKSUM, filechksumtype, filechksum); + if (!strcmp(ext, "DU")) + { + repodata_add_idarray(data, handle, REPOSITORY_KEYS, SOLVABLE_DISKUSAGE); + repodata_add_idarray(data, handle, REPOSITORY_KEYS, REPOKEY_TYPE_DIRNUMNUMARRAY); + } + if (!strcmp(ext, "FL")) + { + repodata_add_idarray(data, handle, REPOSITORY_KEYS, SOLVABLE_FILELIST); + repodata_add_idarray(data, handle, REPOSITORY_KEYS, REPOKEY_TYPE_DIRSTRARRAY); + } + else + { + for (i = 0; susetags_langtags[i]; i += 2) + { + repodata_add_idarray(data, handle, REPOSITORY_KEYS, pool_id2langid(pool, susetags_langtags[i], ext, 1)); + repodata_add_idarray(data, handle, REPOSITORY_KEYS, susetags_langtags[i + 1]); + } + } + repodata_add_flexarray(data, SOLVID_META, REPOSITORY_EXTERNAL, handle); + } + dataiterator_free(&di); +} + + +static inline int +iscompressed(const char *name) +{ + int l = strlen(name); + return l > 3 && !strcmp(name + l - 3, ".gz") ? 1 : 0; +} + + +/* load callback */ int load_stub(Pool *pool, Repodata *data, void *dp) @@ -853,11 +944,11 @@ load_stub(Pool *pool, Repodata *data, void *dp) #endif if (usecachedrepo(data->repo, ext, cinfo->extcookie)) { - printf(" cached]"); fflush(stdout); + printf(" cached]\n"); fflush(stdout); return 1; } #if 1 - printf(" loading]"); fflush(stdout); + printf(" loading]\n"); fflush(stdout); #endif defvendor = repo_lookup_id(data->repo, SOLVID_META, SUSETAGS_DEFAULTVENDOR); descrdir = repo_lookup_str(data->repo, SOLVID_META, SUSETAGS_DESCRDIR); @@ -887,10 +978,10 @@ load_stub(Pool *pool, Repodata *data, void *dp) #endif if (usecachedrepo(data->repo, ext, cinfo->extcookie)) { - printf(" cached]");fflush(stdout); + printf(" cached]\n");fflush(stdout); return 1; } - printf(" loading]"); fflush(stdout); + printf(" loading]\n"); fflush(stdout); filename = repodata_lookup_str(data, SOLVID_META, REPOSITORY_REPOMD_LOCATION); filechksumtype = 0; filechksum = repodata_lookup_bin_checksum(data, SOLVID_META, SUSETAGS_FILE_CHECKSUM, &filechksumtype); @@ -908,66 +999,6 @@ load_stub(Pool *pool, Repodata *data, void *dp) return 0; } -Id susetags_langtags[] = { - SOLVABLE_SUMMARY, REPOKEY_TYPE_STR, - SOLVABLE_DESCRIPTION, REPOKEY_TYPE_STR, - SOLVABLE_EULA, REPOKEY_TYPE_STR, - SOLVABLE_MESSAGEINS, REPOKEY_TYPE_STR, - SOLVABLE_MESSAGEDEL, REPOKEY_TYPE_STR, - SOLVABLE_CATEGORY, REPOKEY_TYPE_ID, - 0, 0 -}; - -void -susetags_add_ext(Repo *repo, Repodata *data) -{ - Pool *pool = repo->pool; - Dataiterator di; - char ext[3]; - Id handle, filechksumtype; - const unsigned char *filechksum; - int i; - - dataiterator_init(&di, pool, repo, SOLVID_META, SUSETAGS_FILE_NAME, 0, 0); - dataiterator_prepend_keyname(&di, SUSETAGS_FILE); - while (dataiterator_step(&di)) - { - if (strncmp(di.kv.str, "packages.", 9) != 0) - continue; - if (!di.kv.str[9] || !di.kv.str[10] || (di.kv.str[11] && di.kv.str[11] != '.')) - continue; - ext[0] = di.kv.str[9]; - ext[1] = di.kv.str[10]; - ext[2] = 0; - if (!susetags_find(repo, di.kv.str, &filechksum, &filechksumtype)) - continue; - handle = repodata_new_handle(data); - repodata_set_str(data, handle, SUSETAGS_FILE_NAME, di.kv.str); - if (filechksumtype) - repodata_set_bin_checksum(data, handle, SUSETAGS_FILE_CHECKSUM, filechksumtype, filechksum); - if (!strcmp(ext, "DU")) - { - repodata_add_idarray(data, handle, REPOSITORY_KEYS, SOLVABLE_DISKUSAGE); - repodata_add_idarray(data, handle, REPOSITORY_KEYS, REPOKEY_TYPE_DIRNUMNUMARRAY); - } - if (!strcmp(ext, "FL")) - { - repodata_add_idarray(data, handle, REPOSITORY_KEYS, SOLVABLE_FILELIST); - repodata_add_idarray(data, handle, REPOSITORY_KEYS, REPOKEY_TYPE_DIRSTRARRAY); - } - else - { - for (i = 0; susetags_langtags[i]; i += 2) - { - repodata_add_idarray(data, handle, REPOSITORY_KEYS, pool_id2langid(pool, susetags_langtags[i], ext, 1)); - repodata_add_idarray(data, handle, REPOSITORY_KEYS, susetags_langtags[i + 1]); - } - } - repodata_add_flexarray(data, SOLVID_META, REPOSITORY_EXTERNAL, handle); - } - dataiterator_free(&di); -} - void read_repos(Pool *pool, struct repoinfo *repoinfos, int nrepoinfos) { @@ -1178,76 +1209,288 @@ read_repos(Pool *pool, struct repoinfo *repoinfos, int nrepoinfos) pool_free(sigpool); } -void -mkselect(Pool *pool, const char *arg, int flags, Queue *out) + +int +str2archid(Pool *pool, char *arch) +{ + Id id; + if (!*arch) + return 0; + id = str2id(pool, arch, 0); + if (id == ARCH_SRC || id == ARCH_NOSRC || id == ARCH_NOARCH) + return id; + if (pool->id2arch && (id > pool->lastarch || !pool->id2arch[id])) + return 0; + return id; +} + +int +depglob(Pool *pool, char *name, Queue *job) { - Id id, p, pp; - Id type = 0; - const char *r, *r2; + Id p, pp; + Id id = str2id(pool, name, 0); + int i, match = 0; - id = str2id(pool, arg, 0); if (id) { FOR_PROVIDES(p, pp, id) { - Solvable *s = pool_id2solvable(pool, p); + Solvable *s = pool->solvables + p; + match = 1; if (s->name == id) { - type = SOLVER_SOLVABLE_NAME; - break; + queue_push2(job, SOLVER_SOLVABLE_NAME, id); + return 1; } - type = SOLVER_SOLVABLE_PROVIDES; + } + if (match) + { + printf("[using capability match for '%s']\n", name); + queue_push2(job, SOLVER_SOLVABLE_PROVIDES, id); + return 1; } } - if (!type) + if (strpbrk(name, "[*?") == 0) + return 0; + /* looks like a name glob. hard work. */ + for (p = 1; p < pool->nsolvables; p++) { - /* did not find a solvable, see if it's a relation */ - if ((r = strpbrk(arg, "<=>")) != 0) + Solvable *s = pool->solvables + p; + if (!s->repo || !pool_installable(pool, s)) + continue; + id = s->name; + if (fnmatch(name, id2str(pool, id), 0) == 0) { - Id rid, rname, revr; - int rflags = 0; - for (r2 = r; r2 > arg && (r2[-1] == ' ' || r2[-1] == '\t'); ) - r2--; - rname = r2 > arg ? strn2id(pool, arg, r2 - arg, 1) : 0; - for (; *r; r++) + for (i = 0; i < job->count; i += 2) + if (job->elements[i] == SOLVER_SOLVABLE_NAME && job->elements[i + 1] == id) + break; + if (i == job->count) + queue_push2(job, SOLVER_SOLVABLE_NAME, id); + match = 1; + } + } + if (match) + return 1; + /* looks like a dep glob. really hard work. */ + for (id = 1; id < pool->ss.nstrings; id++) + { + if (!pool->whatprovides[id]) + continue; + if (fnmatch(name, id2str(pool, id), 0) == 0) + { + if (!match) + printf("[using capability match for '%s']\n", name); + for (i = 0; i < job->count; i += 2) + if (job->elements[i] == SOLVER_SOLVABLE_PROVIDES && job->elements[i + 1] == id) + break; + if (i == job->count) + queue_push2(job, SOLVER_SOLVABLE_PROVIDES, id); + match = 1; + } + } + if (match) + return 1; + return 0; +} + +void +addrelation(Pool *pool, Queue *job, int flags, Id evr) +{ + int i; + for (i = 0; i < job->count; i += 2) + { + if (job->elements[i] != SOLVER_SOLVABLE_NAME && job->elements[i] != SOLVER_SOLVABLE_PROVIDES) + continue; + job->elements[i + 1] = rel2id(pool, job->elements[i + 1], evr, flags, 1); + } +} + +int +limitevr(Pool *pool, char *evr, Queue *job, Id archid) +{ + Queue mq; + Id p, pp, evrid; + int matched = 0; + int i, j; + Solvable *s; + + queue_init(&mq); + for (i = 0; i < job->count; i += 2) + { + queue_empty(&mq); + FOR_JOB_SELECT(p, pp, job->elements[i], job->elements[i + 1]) + { + s = pool_id2solvable(pool, p); + if (archid && s->arch != archid) + continue; + if (evrcmp_str(pool, id2str(pool, s->evr), evr, EVRCMP_MATCH) == 0) + queue_push(&mq, p); + } + if (mq.count) + { + if (!matched && i) { - if (*r == '<') - rflags |= REL_LT; - else if (*r == '=') - rflags |= REL_EQ; - else if (*r == '>') - rflags |= REL_GT; - else + queue_deleten(job, 0, i); + i = 0; + } + matched = 1; + /* if all solvables have the same evr */ + s = pool_id2solvable(pool, mq.elements[0]); + evrid = s->evr; + for (j = 0; j < mq.count; j++) + { + s = pool_id2solvable(pool, mq.elements[j]); + if (s->evr != evrid) break; } - while (*r == ' ' || *r == '\t') - r++; - revr = *r ? str2id(pool, r, 1) : 0; - rid = rname && revr ? rel2id(pool, rname, revr, rflags, 1) : 0; - if (rid) + if (j == mq.count && j > 1) { - FOR_PROVIDES(p, pp, rid) - { - Solvable *s = pool_id2solvable(pool, p); - if (pool_match_nevr(pool, s, rid)) - { - type = SOLVER_SOLVABLE_NAME; - break; - } - type = SOLVER_SOLVABLE_PROVIDES; - } + prune_to_best_arch(pool, &mq); + // prune_to_highest_prio(pool, &mq); + mq.count = 1; + } + if (mq.count > 1) + { + job->elements[i] = SOLVER_SOLVABLE_ONE_OF; + job->elements[i + 1] = pool_queuetowhatprovides(pool, &mq); + } + else + { + job->elements[i] = SOLVER_SOLVABLE; + job->elements[i + 1] = mq.elements[0]; } - if (type) - id = rid; + } + else if (matched) + { + queue_deleten(job, i, 2); + i -= 2; } } - if (type) + queue_free(&mq); + if (matched) + return 1; + if (!archid) { - queue_push(out, type); - queue_push(out, id); + char *r; + if ((r = strrchr(evr, '.')) != 0 && r[1] && (archid = str2archid(pool, r + 1)) != 0) + { + *r = 0; + if (limitevr(pool, evr, job, archid)) + { + *r = '.'; + return 1; + } + *r = '.'; + } } + return 0; } +void +mkselect(Pool *pool, char *name, Queue *job) +{ + char *r, *r2; + Id archid; + + if ((r = strpbrk(name, "<=>")) != 0) + { + /* relation case, support: + * depglob rel + * depglob.rpm rel + */ + int rflags = 0; + int nend = r - name; + for (; *r; r++) + { + if (*r == '<') + rflags |= REL_LT; + else if (*r == '=') + rflags |= REL_EQ; + else if (*r == '>') + rflags |= REL_GT; + else + break; + } + while (*r && *r == ' ' && *r == '\t') + r++; + while (nend && (name[nend - 1] == ' ' || name[nend -1 ] == '\t')) + nend--; + name[nend] = 0; + if (!*name || !*r) + { + fprintf(stderr, "bad relation\n"); + exit(1); + } + if (depglob(pool, name, job)) + { + addrelation(pool, job, rflags, str2id(pool, r, 1)); + return; + } + if ((r2 = strrchr(name, '.')) != 0 && r2[1] && (archid = str2archid(pool, r2 + 1)) != 0) + { + *r2 = 0; + if (depglob(pool, name, job)) + { + *r2 = '.'; + addrelation(pool, job, REL_ARCH, archid); + addrelation(pool, job, rflags, str2id(pool, r, 1)); + return; + } + *r2 = '.'; + } + } + else + { + /* no relation case, support: + * depglob + * depglob.arch + * depglob-version-release + * depglob-version-release.arch + */ + if (depglob(pool, name, job)) + return; + archid = 0; + if ((r = strrchr(name, '.')) != 0 && r[1] && (archid = str2archid(pool, r + 1)) != 0) + { + *r = 0; + if (depglob(pool, name, job)) + { + *r = '.'; + addrelation(pool, job, REL_ARCH, archid); + return; + } + *r = '.'; + } + if ((r = strrchr(name, '-')) != 0) + { + *r = 0; + if (depglob(pool, name, job)) + { + /* have just the version */ + *r = '-'; + if (limitevr(pool, r + 1, job, 0)) + return; + } + if ((r2 = strrchr(name, '-')) != 0) + { + *r = '-'; + *r2 = 0; + if (depglob(pool, name, job)) + { + *r2 = '-'; + if (limitevr(pool, r2 + 1, job, 0)) + return; + } + *r2 = '-'; + } + *r = '-'; + } + } + fprintf(stderr, "nothing matches %s\n", name); + exit(0); +} + + int yesno(const char *str) { @@ -1385,10 +1628,12 @@ int main(int argc, char **argv) { Pool *pool; + Repo *commandlinerepo = 0; Id p, pp; struct repoinfo *repoinfos; int nrepoinfos = 0; int i, mode, newpkgs; + int needwhatprovidesrefresh; Queue job, checkq; Solver *solv = 0; Transaction *trans; @@ -1439,12 +1684,40 @@ main(int argc, char **argv) read_repos(pool, repoinfos, nrepoinfos); // FOR_REPOS(i, repo) // printf("%s: %d solvables\n", repo->name, repo->nsolvables); - pool_addfileprovides(pool); - pool_createwhatprovides(pool); + needwhatprovidesrefresh = 1; queue_init(&job); for (i = 1; i < argc; i++) - mkselect(pool, argv[i], 0, &job); + { + if (mode == 0 || mode == SOLVER_INSTALL) + { + int l; + l = strlen(argv[i]); + if (l > 4 && !strcmp(argv[i] + l - 4, ".rpm") && !access(argv[i], R_OK)) + { + FILE *fp; + if (!commandlinerepo) + commandlinerepo = repo_create(pool, "@commandline"); + fp = fopen(argv[i], "r"); + repo_add_rpms(commandlinerepo, (const char **)argv + i, 1, 0); + queue_push2(&job, SOLVER_SOLVABLE, commandlinerepo->end - 1); + continue; + } + } + if (needwhatprovidesrefresh) + { + pool_addfileprovides(pool); + pool_createwhatprovides(pool); + needwhatprovidesrefresh = 0; + } + mkselect(pool, argv[i], &job); + } + if (needwhatprovidesrefresh) + { + pool_addfileprovides(pool); + pool_createwhatprovides(pool); + needwhatprovidesrefresh = 0; + } if (!job.count && mode == SOLVER_UPDATE) updateall = 1; else if (!job.count) @@ -1467,6 +1740,9 @@ main(int argc, char **argv) printf(" %s\n", sum); } } + queue_free(&job); + pool_free(pool); + free_repoinfos(repoinfos, nrepoinfos); exit(0); } @@ -1657,6 +1933,17 @@ rerunsolver: p = checkq.elements[i]; s = pool_id2solvable(pool, p); + if (s->repo == commandlinerepo) + { + loc = solvable_get_location(s, &medianr); + if (!(newpkgsfps[i] = fopen(loc, "r"))) + { + perror(loc); + exit(1); + } + putchar('.'); + continue; + } cinfo = s->repo->appdata; if (!cinfo) { @@ -1856,5 +2143,6 @@ rerunsolver: solver_free(solv); queue_free(&job); pool_free(pool); + free_repoinfos(repoinfos, nrepoinfos); exit(0); } diff --git a/src/repo.c b/src/repo.c index bfac9f3..f7eb125 100644 --- a/src/repo.c +++ b/src/repo.c @@ -784,6 +784,19 @@ repo_search_md(Repo *repo, Id p, Id keyname, struct matchdata *md) continue; if (keyname && !repodata_precheck_keyname(data, keyname)) continue; + if (keyname == SOLVABLE_FILELIST && !(md->flags & SEARCH_COMPLETE_FILELIST)) + { + /* do not search filelist extensions */ + if (data->state != REPODATA_AVAILABLE) + continue; + if (!repodata_precheck_keyname(data, REPOSITORY_EXTERNAL)) + continue; + for (j = 0; j < data->nkeys; j++) + if (data->keys[j].name == REPOSITORY_EXTERNAL) + break; + if (j == data->nkeys) + continue; + } if (data->state == REPODATA_STUB) { if (keyname) @@ -805,13 +818,6 @@ repo_search_md(Repo *repo, Id p, Id keyname, struct matchdata *md) repodata_search(data, p, keyname, md->flags, repo_matchvalue, md); if (md->stop > SEARCH_NEXT_KEY) break; - if (keyname == SOLVABLE_FILELIST) - { - if (!(md->flags & SEARCH_COMPLETE_FILELIST)) - break; - if (md->matcher.match && (md->flags & (SEARCH_STRINGMASK|SEARCH_NOCASE)) == SEARCH_STRING && repodata_filelistfilter_matches(data, md->matcher.match)) - break; - } } } -- 2.7.4