ref: refs/heads/master
commit af1ae646676cecab2c18a52f43ac9382011b7d78
Author: Michael Schroeder
Date: Tue Jul 21 11:45:41 2009 +0200
- color support in fileconflict checking
- more commands for solv
---
examples/solv.c | 328 +++++++++++++++++++++++++++++++++++----------
ext/pool_fileconflicts.c | 28 +++--
ext/repo_rpmdb.c | 23 +++-
ext/repo_rpmdb.h | 1 +
src/pool.c | 25 ++--
src/repo_solv.c | 2 +-
src/rules.c | 3 +-
src/solver.c | 28 ++++
src/solver.h | 5 +-
9 files changed, 346 insertions(+), 97 deletions(-)
diff --git a/examples/solv.c b/examples/solv.c
index 6a07889..ec00a84 100644
--- a/examples/solv.c
+++ b/examples/solv.c
@@ -7,7 +7,7 @@
/* solv, a little software installer demoing the sat solver library */
-/* things missing:
+/* things available in the library but missing from solv:
* - vendor policy loading
* - soft locks file handling
* - multi version handling
@@ -74,11 +74,13 @@ struct repoinfo {
char *metalink;
char *path;
int type;
- int gpgcheck;
+ int pkgs_gpgcheck;
+ int repo_gpgcheck;
int priority;
int keeppackages;
int metadata_expire;
+ unsigned char cookie[32];
unsigned char extcookie[32];
};
@@ -221,6 +223,9 @@ read_repoinfos(Pool *pool, const char *reposdir, int *nrepoinfosp)
cinfo->alias = strdup(kp + 1);
cinfo->type = TYPE_RPMMD;
cinfo->autorefresh = 1;
+#ifndef FEDORA
+ cinfo->repo_gpgcheck = 1;
+#endif
cinfo->metadata_expire = METADATA_EXPIRE;
continue;
}
@@ -245,7 +250,9 @@ read_repoinfos(Pool *pool, const char *reposdir, int *nrepoinfosp)
else if (!strcmp(kp, "autorefresh"))
cinfo->autorefresh = *vp == '0' ? 0 : 1;
else if (!strcmp(kp, "gpgcheck"))
- cinfo->gpgcheck = *vp == '0' ? 0 : 1;
+ cinfo->pkgs_gpgcheck = *vp == '0' ? 0 : 1;
+ else if (!strcmp(kp, "repo_gpgcheck"))
+ cinfo->repo_gpgcheck = *vp == '0' ? 0 : 1;
else if (!strcmp(kp, "baseurl"))
cinfo->baseurl = strdup(vp);
else if (!strcmp(kp, "mirrorlist"))
@@ -344,13 +351,38 @@ verify_checksum(int fd, const char *file, const unsigned char *chksum, Id chksum
}
char *
-findmetalinkurl(FILE *fp)
+findmetalinkurl(FILE *fp, unsigned char *chksump, Id *chksumtypep)
{
char buf[4096], *bp, *ep;
+
+ if (chksumtypep)
+ *chksumtypep = 0;
while((bp = fgets(buf, sizeof(buf), fp)) != 0)
{
while (*bp == ' ' || *bp == '\t')
bp++;
+ if (chksumtypep && !*chksumtypep && !strncmp(bp, "", 20))
+ {
+ int i;
+
+ bp += 20;
+ memset(chksumtypep, 0, 32);
+ for (i = 0; i < 64; i++)
+ {
+ int c = *bp++;
+ if (c >= '0' && c <= '9')
+ chksump[i / 2] = chksump[i / 2] * 16 + (c - '0');
+ else if (c >= 'a' && c <= 'f')
+ chksump[i / 2] = chksump[i / 2] * 16 + (c - ('a' - 10));
+ else if (c >= 'A' && c <= 'F')
+ chksump[i / 2] = chksump[i / 2] * 16 + (c - ('A' - 10));
+ else
+ break;
+ }
+ if (i == 64)
+ *chksumtypep = REPOKEY_TYPE_SHA256;
+ continue;
+ }
if (strncmp(bp, "');
@@ -396,12 +428,19 @@ curlfopen(struct repoinfo *cinfo, const char *file, int uncompress, const unsign
if (file != cinfo->metalink)
{
FILE *fp = curlfopen(cinfo, cinfo->metalink, 0, 0, 0, 0);
+ unsigned char mlchksum[32];
+ Id mlchksumtype = 0;
if (!fp)
return 0;
- cinfo->baseurl = findmetalinkurl(fp);
+ cinfo->baseurl = findmetalinkurl(fp, mlchksum, &mlchksumtype);
fclose(fp);
if (!cinfo->baseurl)
return 0;
+ if (!chksumtype && mlchksumtype)
+ {
+ chksumtype = mlchksumtype;
+ chksum = mlchksum;
+ }
return curlfopen(cinfo, file, uncompress, chksum, chksumtype, badchecksump);
}
snprintf(url, sizeof(url), "%s", file);
@@ -659,7 +698,14 @@ usecachedrepo(Repo *repo, const char *repoext, unsigned char *cookie, int mark)
/* 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);
+ {
+ int i;
+
+ stb.st_mtime = 0;
+ calc_checksum_stat(&stb, REPOKEY_TYPE_SHA256, cinfo->extcookie);
+ for (i = 0; i < 32; i++)
+ cinfo->extcookie[i] ^= cinfo->cookie[i];
+ }
}
if (mark)
futimes(fileno(fp), 0); /* try to set modification time */
@@ -742,7 +788,14 @@ writecachedrepo(Repo *repo, Repodata *info, const char *repoext, unsigned char *
/* 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);
+ {
+ int i;
+
+ stb.st_mtime = 0;
+ calc_checksum_stat(&stb, REPOKEY_TYPE_SHA256, cinfo->extcookie);
+ for (i = 0; i < 32; i++)
+ cinfo->extcookie[i] ^= cinfo->cookie[i];
+ }
}
if (onepiece)
{
@@ -1113,7 +1166,7 @@ read_repos(Pool *pool, struct repoinfo *repoinfos, int nrepoinfos)
dorefresh = cinfo->autorefresh;
if (dorefresh && cinfo->metadata_expire && stat(calccachepath(repo, 0), &stb) == 0)
{
- if (time(0) - stb.st_mtime < cinfo->metadata_expire)
+ if (cinfo->metadata_expire == -1 || time(0) - stb.st_mtime < cinfo->metadata_expire)
dorefresh = 0;
}
if (!dorefresh && usecachedrepo(repo, 0, 0, 0))
@@ -1135,24 +1188,22 @@ read_repos(Pool *pool, struct repoinfo *repoinfos, int nrepoinfos)
cinfo->repo = 0;
break;
}
- calc_checksum_fp(fp, REPOKEY_TYPE_SHA256, cookie);
- if (usecachedrepo(repo, 0, cookie, 1))
+ calc_checksum_fp(fp, REPOKEY_TYPE_SHA256, cinfo->cookie);
+ if (usecachedrepo(repo, 0, cinfo->cookie, 1))
{
printf(" cached\n");
fclose(fp);
break;
}
- sigfp = curlfopen(cinfo, "repodata/repomd.xml.asc", 0, 0, 0, 0);
-#ifndef FEDORA
- if (!sigfp)
- {
- printf(" unsigned, skipped\n");
- fclose(fp);
- break;
- }
-#endif
- if (sigfp)
+ if (cinfo->repo_gpgcheck)
{
+ sigfp = curlfopen(cinfo, "repodata/repomd.xml.asc", 0, 0, 0, 0);
+ if (!sigfp)
+ {
+ printf(" unsigned, skipped\n");
+ fclose(fp);
+ break;
+ }
if (!sigpool)
sigpool = read_sigs();
if (!checksig(sigpool, fp, sigfp))
@@ -1189,7 +1240,7 @@ read_repos(Pool *pool, struct repoinfo *repoinfos, int nrepoinfos)
repomd_add_ext(repo, data, "filelists");
repodata_internalize(data);
if (!badchecksum)
- writecachedrepo(repo, data, 0, cookie);
+ writecachedrepo(repo, data, 0, cinfo->cookie);
repodata_create_stubs(data);
break;
@@ -1205,32 +1256,35 @@ read_repos(Pool *pool, struct repoinfo *repoinfos, int nrepoinfos)
cinfo->repo = 0;
break;
}
- calc_checksum_fp(fp, REPOKEY_TYPE_SHA256, cookie);
- if (usecachedrepo(repo, 0, cookie, 1))
+ calc_checksum_fp(fp, REPOKEY_TYPE_SHA256, cinfo->cookie);
+ if (usecachedrepo(repo, 0, cinfo->cookie, 1))
{
printf(" cached\n");
fclose(fp);
break;
}
- sigfp = curlfopen(cinfo, "content.asc", 0, 0, 0, 0);
- if (!sigfp)
+ if (cinfo->repo_gpgcheck)
{
- printf(" unsigned, skipped\n");
- fclose(fp);
- break;
- }
- if (sigfp)
- {
- if (!sigpool)
- sigpool = read_sigs();
- if (!checksig(sigpool, fp, sigfp))
+ sigfp = curlfopen(cinfo, "content.asc", 0, 0, 0, 0);
+ if (!sigfp)
{
- printf(" checksig failed, skipped\n");
- fclose(sigfp);
+ printf(" unsigned, skipped\n");
fclose(fp);
break;
}
- fclose(sigfp);
+ if (sigfp)
+ {
+ if (!sigpool)
+ sigpool = read_sigs();
+ if (!checksig(sigpool, fp, sigfp))
+ {
+ printf(" checksig failed, skipped\n");
+ fclose(sigfp);
+ fclose(fp);
+ break;
+ }
+ fclose(sigfp);
+ }
}
repo_add_content(repo, fp, 0);
fclose(fp);
@@ -1255,7 +1309,7 @@ read_repos(Pool *pool, struct repoinfo *repoinfos, int nrepoinfos)
susetags_add_ext(repo, data);
repodata_internalize(data);
if (!badchecksum)
- writecachedrepo(repo, data, 0, cookie);
+ writecachedrepo(repo, data, 0, cinfo->cookie);
repodata_create_stubs(data);
break;
default:
@@ -1715,6 +1769,34 @@ nscallback(Pool *pool, void *data, Id name, Id evr)
return 0;
}
+#define MODE_LIST 0
+#define MODE_INSTALL 1
+#define MODE_ERASE 2
+#define MODE_UPDATE 3
+#define MODE_DISTUPGRADE 4
+#define MODE_VERIFY 5
+#define MODE_PATCH 6
+#define MODE_INFO 7
+#define MODE_REPOLIST 8
+#define MODE_SEARCH 9
+
+void
+usage(int r)
+{
+ fprintf(stderr, "Usage: solv COMMAND <select>\n");
+ fprintf(stderr, "\n");
+ fprintf(stderr, " distupgrade: replace installed packages with\n");
+ fprintf(stderr, " versions from the repositories\n");
+ fprintf(stderr, " erase: erase installed packages\n");
+ fprintf(stderr, " info: display package information\n");
+ fprintf(stderr, " install: install packages\n");
+ fprintf(stderr, " list: list packages\n");
+ fprintf(stderr, " repos: list enabled repositories\n");
+ fprintf(stderr, " search: search name/summary/description\n");
+ fprintf(stderr, " update: update installed packages\n");
+ fprintf(stderr, "\n");
+ exit(r);
+}
int
main(int argc, char **argv)
@@ -1725,57 +1807,132 @@ main(int argc, char **argv)
Id p, pp;
struct repoinfo *repoinfos;
int nrepoinfos = 0;
- int i, mode, newpkgs;
+ int i, mainmode, mode, newpkgs;
Queue job, checkq;
Solver *solv = 0;
Transaction *trans;
char inbuf[128], *ip;
- int updateall = 0;
- int distupgrade = 0;
- int patchmode = 0;
+ int allpkgs = 0;
FILE **newpkgsfps;
struct fcstate fcstate;
argc--;
argv++;
if (!argv[0])
+ usage(1);
+ if (!strcmp(argv[0], "install") || !strcmp(argv[0], "in"))
{
- fprintf(stderr, "Usage: solv install|erase|update|show <select>\n");
- exit(1);
+ mainmode = MODE_INSTALL;
+ mode = SOLVER_INSTALL;
}
- if (!strcmp(argv[0], "install") || !strcmp(argv[0], "in"))
- mode = SOLVER_INSTALL;
else if (!strcmp(argv[0], "patch"))
{
- mode = SOLVER_UPDATE;
- patchmode = 1;
+ mainmode = MODE_PATCH;
+ mode = SOLVER_INSTALL;
}
else if (!strcmp(argv[0], "erase") || !strcmp(argv[0], "rm"))
- mode = SOLVER_ERASE;
- else if (!strcmp(argv[0], "show"))
- mode = 0;
+ {
+ mainmode = MODE_ERASE;
+ mode = SOLVER_ERASE;
+ }
+ else if (!strcmp(argv[0], "list"))
+ {
+ mainmode = MODE_LIST;
+ mode = 0;
+ }
+ else if (!strcmp(argv[0], "info"))
+ {
+ mainmode = MODE_INFO;
+ mode = 0;
+ }
+ else if (!strcmp(argv[0], "search"))
+ {
+ mainmode = MODE_SEARCH;
+ mode = 0;
+ }
+ else if (!strcmp(argv[0], "verify"))
+ {
+ mainmode = MODE_VERIFY;
+ mode = SOLVER_VERIFY;
+ }
else if (!strcmp(argv[0], "update") || !strcmp(argv[0], "up"))
- mode = SOLVER_UPDATE;
+ {
+ mainmode = MODE_UPDATE;
+ mode = SOLVER_UPDATE;
+ }
else if (!strcmp(argv[0], "dist-upgrade") || !strcmp(argv[0], "dup"))
{
+ mainmode = MODE_DISTUPGRADE;
mode = SOLVER_UPDATE;
- distupgrade = 1;
}
- else
+ else if (!strcmp(argv[0], "repos") || !strcmp(argv[0], "repolist") || !strcmp(argv[0], "lr"))
{
- fprintf(stderr, "Usage: solv install|erase|update|show <select>\n");
- exit(1);
+ mainmode = MODE_REPOLIST;
+ mode = 0;
}
+ else
+ usage(1);
pool = pool_create();
+#ifdef FEDORA
+ pool->obsoleteusescolors = 1;
+#endif
pool_setloadcallback(pool, load_stub, 0);
pool->nscallback = nscallback;
// pool_setdebuglevel(pool, 2);
setarch(pool);
repoinfos = read_repoinfos(pool, REPOINFO_PATH, &nrepoinfos);
+
+ if (mainmode == MODE_REPOLIST)
+ {
+ int j = 1;
+ for (i = 0; i < nrepoinfos; i++)
+ {
+ struct repoinfo *cinfo = repoinfos + i;
+ if (!cinfo->enabled)
+ continue;
+ printf("%d: %-20s %s\n", j++, cinfo->alias, cinfo->name);
+ }
+ exit(0);
+ }
+
read_repos(pool, repoinfos, nrepoinfos);
- if (mode == 0 || mode == SOLVER_INSTALL)
+ if (mainmode == MODE_SEARCH)
+ {
+ Dataiterator di;
+ Map m;
+ if (argc != 2)
+ usage(1);
+ map_init(&m, pool->nsolvables);
+ dataiterator_init(&di, pool, 0, 0, 0, argv[1], SEARCH_SUBSTRING|SEARCH_NOCASE);
+ dataiterator_set_keyname(&di, SOLVABLE_NAME);
+ dataiterator_set_search(&di, 0, 0);
+ while (dataiterator_step(&di))
+ MAPSET(&m, di.solvid);
+ dataiterator_set_keyname(&di, SOLVABLE_SUMMARY);
+ dataiterator_set_search(&di, 0, 0);
+ while (dataiterator_step(&di))
+ MAPSET(&m, di.solvid);
+ dataiterator_set_keyname(&di, SOLVABLE_DESCRIPTION);
+ dataiterator_set_search(&di, 0, 0);
+ while (dataiterator_step(&di))
+ MAPSET(&m, di.solvid);
+ dataiterator_free(&di);
+
+ for (p = 1; p < pool->nsolvables; p++)
+ {
+ Solvable *s = pool_id2solvable(pool, p);
+ if (!MAPTST(&m, p))
+ continue;
+ printf(" - %s: %s\n", solvable2str(pool, s), solvable_lookup_str(s, SOLVABLE_SUMMARY));
+ }
+ map_free(&m);
+ exit(0);
+ }
+
+
+ if (mainmode == MODE_LIST || mainmode == MODE_INSTALL)
{
for (i = 1; i < argc; i++)
{
@@ -1807,33 +1964,55 @@ main(int argc, char **argv)
queue_init(&job);
for (i = 1; i < argc; i++)
{
+ Queue job2;
+ int j;
+
if (commandlinepkgs && commandlinepkgs[i])
{
queue_push2(&job, SOLVER_SOLVABLE, commandlinepkgs[i]);
continue;
}
- mkselect(pool, mode, argv[i], &job);
+ queue_init(&job2);
+ mkselect(pool, mode, argv[i], &job2);
+ for (j = 0; j < job2.count; j++)
+ queue_push(&job, job2.elements[j]);
+ queue_free(&job2);
}
- if (!job.count && mode == SOLVER_UPDATE)
- updateall = 1;
- else if (!job.count)
+
+ if (!job.count && mainmode != MODE_UPDATE && mainmode != MODE_DISTUPGRADE && mainmode != MODE_VERIFY && mainmode != MODE_PATCH)
{
printf("no package matched\n");
exit(1);
}
- if (!mode)
+ if (!job.count)
+ allpkgs = 1;
+
+ if (mainmode == MODE_LIST || mainmode == MODE_INFO)
{
- /* show mode, no solver needed */
+ /* list mode, no solver needed */
for (i = 0; i < job.count; i += 2)
{
FOR_JOB_SELECT(p, pp, job.elements[i], job.elements[i + 1])
{
Solvable *s = pool_id2solvable(pool, p);
- const char *sum = solvable_lookup_str_lang(s, SOLVABLE_SUMMARY, "de");
- printf(" - %s [%s]\n", solvable2str(pool, s), s->repo->name);
- if (sum)
- printf(" %s\n", sum);
+ if (mainmode == MODE_INFO)
+ {
+ printf("Name: %s\n", solvable2str(pool, s));
+ printf("Repo: %s\n", s->repo->name);
+ printf("Summary: %s\n", solvable_lookup_str(s, SOLVABLE_SUMMARY));
+ printf("Url: %s\n", solvable_lookup_str(s, SOLVABLE_URL));
+ printf("License: %s\n", solvable_lookup_str(s, SOLVABLE_LICENSE));
+ printf("Description:\n%s\n", solvable_lookup_str(s, SOLVABLE_DESCRIPTION));
+ printf("\n");
+ }
+ else
+ {
+ const char *sum = solvable_lookup_str_lang(s, SOLVABLE_SUMMARY, "de");
+ printf(" - %s [%s]\n", solvable2str(pool, s), s->repo->name);
+ if (sum)
+ printf(" %s\n", sum);
+ }
}
}
queue_free(&job);
@@ -1843,7 +2022,7 @@ main(int argc, char **argv)
exit(0);
}
- if (updateall && patchmode)
+ if (mainmode == MODE_PATCH)
{
int pruneyou = 0;
Map installedmap;
@@ -1855,8 +2034,6 @@ main(int argc, char **argv)
MAPSET(&installedmap, p);
/* install all patches */
- updateall = 0;
- mode = SOLVER_INSTALL;
for (p = 1; p < pool->nsolvables; p++)
{
const char *type;
@@ -1900,6 +2077,7 @@ main(int argc, char **argv)
{
if (mode == SOLVER_UPDATE)
{
+ /* make update of not installed packages an install */
FOR_JOB_SELECT(p, pp, job.elements[i], job.elements[i + 1])
if (pool->installed && pool->solvables[p].repo == pool->installed)
break;
@@ -1925,15 +2103,19 @@ rerunsolver:
solv = solver_create(pool);
solv->ignorealreadyrecommended = 1;
- solv->updatesystem = updateall;
- solv->dosplitprovides = updateall;
- if (updateall && distupgrade)
+ solv->updatesystem = allpkgs && (mainmode == MODE_UPDATE || mainmode == MODE_DISTUPGRADE);
+ solv->dosplitprovides = solv->updatesystem;
+ solv->fixsystem = allpkgs && (mainmode == MODE_VERIFY);
+ if (mainmode == MODE_DISTUPGRADE)
{
solv->distupgrade = 1;
solv->allowdowngrade = 1;
solv->allowarchchange = 1;
solv->allowvendorchange = 1;
}
+ /* infarch check currently doesn't work with colors */
+ solv->noinfarchcheck = pool->obsoleteusescolors;
+
// queue_push2(&job, SOLVER_DISTUPGRADE, 3);
solver_solve(solv, &job);
if (!solv->problems.count)
diff --git a/ext/pool_fileconflicts.c b/ext/pool_fileconflicts.c
index ed0a41c..0e91e9b 100644
--- a/ext/pool_fileconflicts.c
+++ b/ext/pool_fileconflicts.c
@@ -214,7 +214,7 @@ findfileconflicts2_cb(void *cbdatav, const char *fn, int fmode, const char *md5)
{
struct cbdata *cbdata = cbdatav;
unsigned int hx = strhash(fn);
- char md5padded[33];
+ char md5padded[34];
if (!hx)
hx = strlen(fn) + 1;
@@ -222,9 +222,10 @@ findfileconflicts2_cb(void *cbdatav, const char *fn, int fmode, const char *md5)
return;
strncpy(md5padded, md5, 32);
md5padded[32] = 0;
+ md5padded[33] = fmode >> 24;
// printf("%d, hx %x -> %s %d %s\n", cbdata->idx, hx, fn, fmode, md5);
queue_push(&cbdata->files, cbdata->filesspacen);
- addfilesspace(cbdata, (unsigned char *)md5padded, 33);
+ addfilesspace(cbdata, (unsigned char *)md5padded, 34);
addfilesspace(cbdata, (unsigned char *)fn, strlen(fn) + 1);
}
@@ -367,6 +368,11 @@ pool_findfileconflicts(Pool *pool, Queue *pkgs, int cutoff, Queue *conflicts, vo
{
int pend, ii, jj;
int pidx = cbdata.lookat.elements[i + 1];
+ int iterflags;
+
+ iterflags = RPM_ITERATE_FILELIST_WITHMD5;
+ if (pool->obsoleteusescolors)
+ iterflags |= RPM_ITERATE_FILELIST_WITHCOL;
p = pkgs->elements[pidx];
hx = cbdata.lookat.elements[i];
if (cbdata.lookat.elements[i + 2] != hx)
@@ -380,7 +386,7 @@ pool_findfileconflicts(Pool *pool, Queue *pkgs, int cutoff, Queue *conflicts, vo
handle = (*handle_cb)(pool, p, handle_cbdata);
if (!handle)
continue;
- rpm_iterate_filelist(handle, RPM_ITERATE_FILELIST_WITHMD5, findfileconflicts2_cb, &cbdata);
+ rpm_iterate_filelist(handle, iterflags, findfileconflicts2_cb, &cbdata);
pend = cbdata.files.count;
for (j = i + 2; j < cbdata.lookat.count && cbdata.lookat.elements[j] == hx; j++)
@@ -393,15 +399,19 @@ pool_findfileconflicts(Pool *pool, Queue *pkgs, int cutoff, Queue *conflicts, vo
handle = (*handle_cb)(pool, q, handle_cbdata);
if (!handle)
continue;
- rpm_iterate_filelist(handle, RPM_ITERATE_FILELIST_WITHMD5, findfileconflicts2_cb, &cbdata);
+ rpm_iterate_filelist(handle, iterflags, findfileconflicts2_cb, &cbdata);
for (ii = 0; ii < pend; ii++)
for (jj = pend; jj < cbdata.files.count; jj++)
{
- if (strcmp((char *)cbdata.filesspace + cbdata.files.elements[ii] + 33, (char *)cbdata.filesspace + cbdata.files.elements[jj] + 33))
- continue;
- if (!strcmp((char *)cbdata.filesspace + cbdata.files.elements[ii], (char *)cbdata.filesspace + cbdata.files.elements[jj]))
- continue;
- queue_push(conflicts, str2id(pool, (char *)cbdata.filesspace + cbdata.files.elements[ii] + 33, 1));
+ char *fsi = (char *)cbdata.filesspace + cbdata.files.elements[ii];
+ char *fsj = (char *)cbdata.filesspace + cbdata.files.elements[jj];
+ if (strcmp(fsi + 34, fsj + 34))
+ continue; /* different file names */
+ if (!strcmp(fsi, fsj))
+ continue; /* md5 sum matches */
+ if (pool->obsoleteusescolors && fsi[33] && fsj[33] && (fsi[33] & fsj[33]) == 0)
+ continue; /* colors do not conflict */
+ queue_push(conflicts, str2id(pool, (char *)cbdata.filesspace + cbdata.files.elements[ii] + 34, 1));
queue_push(conflicts, p);
queue_push(conflicts, str2id(pool, (char *)cbdata.filesspace + cbdata.files.elements[ii], 1));
queue_push(conflicts, q);
diff --git a/ext/repo_rpmdb.c b/ext/repo_rpmdb.c
index 911f1af..ed33bc9 100644
--- a/ext/repo_rpmdb.c
+++ b/ext/repo_rpmdb.c
@@ -1908,6 +1908,7 @@ rpm_iterate_filelist(void *rpmhandle, int flags, void (*cb)(void *, const char *
char **md = 0;
char **lt = 0;
unsigned int *di, diidx;
+ unsigned int *co = 0;
unsigned int lastdir;
int lastdirl;
unsigned int *fm;
@@ -1963,6 +1964,20 @@ rpm_iterate_filelist(void *rpmhandle, int flags, void (*cb)(void *, const char *
return;
}
}
+ if ((flags & RPM_ITERATE_FILELIST_WITHCOL) != 0)
+ {
+ co = headint32array(rpmhead, TAG_FILECOLORS, &cnt2);
+ if (!co || cnt != cnt2)
+ {
+ sat_free(co);
+ sat_free(md);
+ sat_free(fm);
+ sat_free(di);
+ sat_free(bn);
+ sat_free(dn);
+ return;
+ }
+ }
lastdir = dcnt;
lastdirl = 0;
for (i = 0; i < cnt; i++)
@@ -2005,9 +2020,12 @@ rpm_iterate_filelist(void *rpmhandle, int flags, void (*cb)(void *, const char *
}
}
if (!md5p)
- md5p = "";
+ {
+ sprintf(md5, "%08x%08x", (fm[i] >> 12) & 65535, 0);
+ md5p = md5;
+ }
}
- (*cb)(cbdata, space, fm[i], md5p);
+ (*cb)(cbdata, space, co ? (fm[i] | co[i] << 24) : fm[i], md5p);
}
sat_free(space);
sat_free(lt);
@@ -2016,6 +2034,7 @@ rpm_iterate_filelist(void *rpmhandle, int flags, void (*cb)(void *, const char *
sat_free(di);
sat_free(bn);
sat_free(dn);
+ sat_free(co);
}
char *
diff --git a/ext/repo_rpmdb.h b/ext/repo_rpmdb.h
index 78dd2f3..b801a48 100644
--- a/ext/repo_rpmdb.h
+++ b/ext/repo_rpmdb.h
@@ -24,6 +24,7 @@ void repo_add_pubkeys(Repo *repo, const char **keys, int nkeys, int flags);
#define RPM_ITERATE_FILELIST_ONLYDIRS (1 << 0)
#define RPM_ITERATE_FILELIST_WITHMD5 (1 << 1)
+#define RPM_ITERATE_FILELIST_WITHCOL (1 << 2)
void *rpm_byrpmdbid(Id rpmdbid, const char *rootdir, void **statep);
void *rpm_byfp(FILE *fp, const char *name, void **statep);
diff --git a/src/pool.c b/src/pool.c
index eae97e1..4bfc2de 100644
--- a/src/pool.c
+++ b/src/pool.c
@@ -949,6 +949,7 @@ pool_addfileprovides_search(Pool *pool, struct addfileprovides_cbdata *cbd, stru
end = pool->nsolvables;
}
flags = 0;
+ map_init(&providedids, pool->ss.nstrings);
for (p = start, s = pool->solvables + p; p < end; p++, s++)
{
repo = s->repo;
@@ -986,12 +987,11 @@ pool_addfileprovides_search(Pool *pool, struct addfileprovides_cbdata *cbd, stru
data = nextdata; /* no direct hit, use next repodata */
if (data)
{
- map_init(&providedids, pool->ss.nstrings);
+ map_empty(&providedids);
repodata_search(data, SOLVID_META, REPOSITORY_ADDEDFILEPROVIDES, 0, addfileprovides_setid_cb, &providedids);
for (i = 0; i < cbd->nfiles; i++)
if (!MAPTST(&providedids, cbd->ids[i]))
break;
- map_free(&providedids);
dataincludes = i == cbd->nfiles;
}
oldrepo = repo;
@@ -1009,18 +1009,23 @@ pool_addfileprovides_search(Pool *pool, struct addfileprovides_cbdata *cbd, stru
if (ffldata)
{
for (i = 0; i < cbd->nfiles; i++)
- if (!repodata_filelistfilter_matches(ffldata, id2str(pool, cbd->ids[i])))
- {
-#if 0
- printf("Need the complete filelist in repo %s because of %s\n", repo->name, id2str(pool, cbd->ids[i]));
-#endif
- flags = SEARCH_COMPLETE_FILELIST;
- break;
- }
+ {
+ if (data && p >= data->start && MAPTST(&providedids, cbd->ids[i]))
+ continue;
+ if (!repodata_filelistfilter_matches(ffldata, id2str(pool, cbd->ids[i])))
+ {
+ #if 0
+ printf("Need the complete filelist in repo %s because of %s\n", repo->name, id2str(pool, cbd->ids[i]));
+ #endif
+ flags = SEARCH_COMPLETE_FILELIST;
+ break;
+ }
+ }
}
}
repo_search(repo, p, SOLVABLE_FILELIST, 0, flags, addfileprovides_cb, cbd);
}
+ map_free(&providedids);
}
void
diff --git a/src/repo_solv.c b/src/repo_solv.c
index ca355c8..848eb93 100644
--- a/src/repo_solv.c
+++ b/src/repo_solv.c
@@ -514,7 +514,7 @@ repo_add_solv_flags(Repo *repo, FILE *fp, int flags)
/* make sure that we exactly replace the stub repodata */
if (parent->end - parent->start != numsolv)
{
- pool_debug(pool, SAT_ERROR, "sub-repository solvable number doesn't match main repository (%d - %d)\n", parent->end - parent->start, numsolv);
+ pool_debug(pool, SAT_ERROR, "sub-repository solvable number does not match main repository (%d - %d)\n", parent->end - parent->start, numsolv);
return SOLV_ERROR_CORRUPT;
}
for (i = 0; i < numsolv; i++)
diff --git a/src/rules.c b/src/rules.c
index b673e80..02a918d 100644
--- a/src/rules.c
+++ b/src/rules.c
@@ -500,7 +500,8 @@ solver_addrpmrulesforsolvable(Solver *solv, Solvable *s, Map *m)
dontfix = 0;
if (installed /* Installed system available */
&& !solv->fixsystem /* NOT repair errors in rpm dependency graph */
- && s->repo == installed) /* solvable is installed? */
+ && s->repo == installed /* solvable is installed */
+ && (!solv->fixmap.size || !MAPTST(&solv->fixmap, n - installed->start)))
{
dontfix = 1; /* dont care about broken rpm deps */
}
diff --git a/src/solver.c b/src/solver.c
index 98f264d..be10f0b 100644
--- a/src/solver.c
+++ b/src/solver.c
@@ -1289,6 +1289,7 @@ solver_free(Solver *solv)
map_free(&solv->noobsoletes);
map_free(&solv->updatemap);
+ map_free(&solv->fixmap);
map_free(&solv->dupmap);
map_free(&solv->dupinvolvedmap);
@@ -2429,6 +2430,30 @@ solver_solve(Solver *solv, Queue *job)
*/
if (installed)
{
+ /* check for verify jobs */
+ for (i = 0; i < job->count; i += 2)
+ {
+ how = job->elements[i];
+ what = job->elements[i + 1];
+ select = how & SOLVER_SELECTMASK;
+ switch (how & SOLVER_JOBMASK)
+ {
+ case SOLVER_VERIFY:
+ FOR_JOB_SELECT(p, pp, select, what)
+ {
+ s = pool->solvables + p;
+ if (!solv->installed || s->repo != solv->installed)
+ continue;
+ if (!solv->fixmap.size)
+ map_grow(&solv->fixmap, solv->installed->end - solv->installed->start);
+ MAPSET(&solv->fixmap, p - solv->installed->start);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
oldnrules = solv->nrules;
POOL_DEBUG(SAT_DEBUG_SCHUBI, "*** create rpm rules for installed solvables ***\n");
FOR_REPO_SOLVABLES(installed, p, s)
@@ -2702,6 +2727,9 @@ solver_solve(Solver *solv, Queue *job)
MAPSET(&solv->updatemap, p - solv->installed->start);
}
break;
+ case SOLVER_VERIFY:
+ POOL_DEBUG(SAT_DEBUG_JOB, "job: %sverify %s\n", weak ? "weak " : "", solver_select2str(solv, select, what));
+ break;
case SOLVER_WEAKENDEPS:
POOL_DEBUG(SAT_DEBUG_JOB, "job: %sweaken deps %s\n", weak ? "weak " : "", solver_select2str(solv, select, what));
if (select != SOLVER_SOLVABLE)
diff --git a/src/solver.h b/src/solver.h
index 7a92365..096d378 100644
--- a/src/solver.h
+++ b/src/solver.h
@@ -81,7 +81,9 @@ typedef struct _Solver {
Map noobsoletes; /* ignore obsoletes for these
(multiinstall) */
- Map updatemap; /* bring those packages to the newest version */
+ Map updatemap; /* bring those installed packages to the newest version */
+ Map fixmap; /* fix those packages */
+
Queue weakruleq; /* index into 'rules' for weak ones */
Map weakrulemap; /* map rule# to '1' for weak rules, 1..learntrules */
@@ -221,6 +223,7 @@ typedef struct _Solver {
#define SOLVER_NOOBSOLETES 0x0500
#define SOLVER_LOCK 0x0600
#define SOLVER_DISTUPGRADE 0x0700
+#define SOLVER_VERIFY 0x0800
#define SOLVER_JOBMASK 0xff00
--
To unsubscribe, e-mail: zypp-commit+unsubscribe@opensuse.org
For additional commands, e-mail: zypp-commit+help@opensuse.org