This file contains the major changes between
libsolv versions:
+Version 0.6.36
+- bug fixes:
+ * do not autouninstall packages because of forcebest updates
+ * fixed a couple of null pointer derefs and potential memory
+ leaks
+ * no longer disable infarch rules when they don't conflict with
+ the job
+ * fix cleandeps updates not updating all packages
+ * fix SOLVER_FLAG_FOCUS_BEST updateing packages without reason
+ * be more correct with multiversion packages that obsolete their
+ own name
+
Version 0.6.35
- new configuration options:
* ENABLE_ZSTD_COMPRESSION: support zstd compression
SET(LIBSOLV_MAJOR "0")
SET(LIBSOLV_MINOR "6")
-SET(LIBSOLV_PATCH "35")
+SET(LIBSOLV_PATCH "36")
Do not read any packages from the rpm database. This is useful
together with *-p* to only convert SUSE products.
+*-C*::
+Include the package changelog in the generated solv file.
+
*-X*::
Autoexpand SUSE pattern and product provides into packages.
socks[i] = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (socks[i] >= 0)
{
- fcntl(socks[i], F_SETFL, O_NONBLOCK);
+ if (fcntl(socks[i], F_SETFL, O_NONBLOCK) == -1)
+ {
+ close(socks[i]);
+ socks[i] = -1;
+ }
if (connect(socks[i], result->ai_addr, result->ai_addrlen) == -1)
{
if (errno != EINPROGRESS)
#if defined(ENABLE_APPDATA)
#include "repo_appdata.h"
#endif
+#ifdef SUSE
+#include "repo_autopattern.h"
+#endif
#include "transaction.h"
#include "repoinfo.h"
if (ofp)
fclose(ofp);
repo_internalize(repo);
+#ifdef SUSE
+ repo_add_autopattern(repo, 0);
+#endif
writecachedrepo(cinfo, 0, 0);
return 1;
}
if (repo == pool->installed)
flags |= ADD_NO_AUTOPRODUCTS; /* no auto products for installed repos */
- pattern_id = pool_str2id(pool, "pattern()", 9);
- product_id = pool_str2id(pool, "product()", 9);
+ pattern_id = pool_str2id(pool, "pattern()", 1);
+ product_id = pool_str2id(pool, "product()", 1);
FOR_REPO_SOLVABLES(repo, p, s)
{
const char *n = pool_id2str(pool, s->name);
while (value)
{
char *p = strchr(value, ',');
- if (*p)
+ if (p)
*p++ = 0;
if (*value)
repodata_add_poolstr_array(pd->data, SOLVID_META, REPOSITORY_UPDATES, value);
char **cn;
char **cx;
uint32_t *ct;
- int i, cnc, cxc, ctc;
+ int i, cnc, cxc, ctc = 0;
Queue hq;
ct = headint32array(rpmhead, TAG_CHANGELOGTIME, &ctc);
if (fread(lead, 96 + 16, 1, fp) != 1 || getu32(lead) != 0xedabeedb)
{
pool_error(pool, -1, "%s: not a rpm", rpm);
+ solv_chksum_free(leadsigchksumh, 0);
+ solv_chksum_free(chksumh, 0);
fclose(fp);
return 0;
}
if (lead[78] != 0 || lead[79] != 5)
{
pool_error(pool, -1, "%s: not a rpm v5 header", rpm);
+ solv_chksum_free(leadsigchksumh, 0);
+ solv_chksum_free(chksumh, 0);
fclose(fp);
return 0;
}
if (getu32(lead + 96) != 0x8eade801)
{
pool_error(pool, -1, "%s: bad signature header", rpm);
+ solv_chksum_free(leadsigchksumh, 0);
+ solv_chksum_free(chksumh, 0);
fclose(fp);
return 0;
}
if (sigcnt >= MAX_SIG_CNT || sigdsize >= MAX_SIG_DSIZE)
{
pool_error(pool, -1, "%s: bad signature header", rpm);
+ solv_chksum_free(leadsigchksumh, 0);
+ solv_chksum_free(chksumh, 0);
fclose(fp);
return 0;
}
{
if (!headfromfp(&state, rpm, fp, lead + 96, sigcnt, sigdsize, sigpad, chksumh, leadsigchksumh))
{
+ solv_chksum_free(leadsigchksumh, 0);
+ solv_chksum_free(chksumh, 0);
fclose(fp);
return 0;
}
if (fread(lead, l, 1, fp) != 1)
{
pool_error(pool, -1, "%s: unexpected EOF", rpm);
+ solv_chksum_free(leadsigchksumh, 0);
+ solv_chksum_free(chksumh, 0);
fclose(fp);
return 0;
}
if (fread(lead, 16, 1, fp) != 1)
{
pool_error(pool, -1, "%s: unexpected EOF", rpm);
+ solv_chksum_free(chksumh, 0);
fclose(fp);
return 0;
}
if (getu32(lead) != 0x8eade801)
{
pool_error(pool, -1, "%s: bad header", rpm);
+ solv_chksum_free(chksumh, 0);
fclose(fp);
return 0;
}
if (sigcnt >= MAX_HDR_CNT || sigdsize >= MAX_HDR_DSIZE)
{
pool_error(pool, -1, "%s: bad header", rpm);
+ solv_chksum_free(chksumh, 0);
fclose(fp);
return 0;
}
if (!headfromfp(&state, rpm, fp, lead, sigcnt, sigdsize, 0, chksumh, 0))
{
+ solv_chksum_free(chksumh, 0);
fclose(fp);
return 0;
}
Id flags, id, id2, namespaceid = 0;
struct oplist *op;
+ if (!s)
+ return 0;
while (*s == ' ' || *s == '\t')
s++;
if (!strncmp(s, "namespace:", 10))
Queue q;
job |= SOLVER_SOLVABLE_ONE_OF;
queue_init(&q);
- if (npieces > 3 && strcmp(pieces[2], "nothing") != 0)
+ if (npieces > 2 && strcmp(pieces[2], "nothing") != 0)
{
for (i = 2; i < npieces; i++)
{
if ((rtype & SOLVER_RULE_TYPEMASK) == SOLVER_RULE_JOB)
{
const char *js = testcase_job2str(pool, rq.elements[i + 2], rq.elements[i + 3]);
- char *s = pool_tmpjoin(pool, altprefix, num, " job ");
+ char *s = pool_tmpjoin(pool, altprefix, num, "job ");
s = pool_tmpappend(pool, s, js, 0);
strqueue_push(&sq, s);
}
s = pool_tmpappend(pool, s, " requires ", testcase_dep2str(pool, rq.elements[i + 3]));
strqueue_push(&sq, s);
}
+ else if (rtype == SOLVER_RULE_UPDATE || rtype == SOLVER_RULE_FEATURE)
+ {
+ const char *js = testcase_solvid2str(pool, rq.elements[i + 1]);
+ char *s = pool_tmpjoin(pool, altprefix, num, "update ");
+ s = pool_tmpappend(pool, s, js, 0);
+ strqueue_push(&sq, s);
+ }
}
}
for (i = 0; i < q.count; i++)
Id lowscore;
FILE *fp;
Strqueue sq;
- char *cmd, *out;
+ char *cmd, *out, *result;
const char *s;
if (!testcasename)
if ((resultflags & ~TESTCASE_RESULT_REUSE_SOLVER) != 0)
{
- char *result;
cmd = 0;
for (i = 0; resultflags2str[i].str; i++)
if ((resultflags & resultflags2str[i].flag) != 0)
result = testcase_solverresult(solv, resultflags);
if (!strcmp(resultname, "<inline>"))
{
- int i;
Strqueue rsq;
strqueue_init(&rsq);
strqueue_split(&rsq, result);
if (fclose(fp))
{
pool_error(solv->pool, 0, "testcase_write: write error");
+ solv_free(result);
strqueue_free(&sq);
return 0;
}
solv_free(result);
}
- cmd = strqueue_join(&sq);
+ result = strqueue_join(&sq);
+ strqueue_free(&sq);
out = pool_tmpjoin(pool, dir, "/", testcasename);
if (!(fp = fopen(out, "w")))
{
pool_error(solv->pool, 0, "testcase_write: could not open '%s' for writing", out);
- strqueue_free(&sq);
+ solv_free(result);
return 0;
}
- if (*cmd && fwrite(cmd, strlen(cmd), 1, fp) != 1)
+ if (*result && fwrite(result, strlen(result), 1, fp) != 1)
{
pool_error(solv->pool, 0, "testcase_write: write error");
- strqueue_free(&sq);
+ solv_free(result);
fclose(fp);
return 0;
}
if (fclose(fp))
{
pool_error(solv->pool, 0, "testcase_write: write error");
- strqueue_free(&sq);
+ solv_free(result);
return 0;
}
- solv_free(cmd);
- strqueue_free(&sq);
+ solv_free(result);
return 1;
}
{
int i = strlen(pieces[1]);
s = strchr(pieces[1], '(');
- if (!s && pieces[1][i - 1] != ')')
+ if (!s || pieces[1][i - 1] != ')')
{
pool_error(pool, 0, "testcase_read: bad namespace '%s'", pieces[1]);
}
-------------------------------------------------------------------
+Thu Jun 27 16:36:00 CEST 2019 - mls@suse.de
+
+- make cleandeps jobs on patterns work [bnc#1137977]
+- fix SOLVER_FLAG_FOCUS_BEST updateing packages without reason
+- be more correct with multiversion packages that obsolete their
+ own name [bnc#1127155]
+- always prefer to stay with the same package name if there are
+ multiple alternatives [bnc#1131823]
+- fix cleandeps updates not updating all packages
+- fixed a couple of null pointer derefs
+ [bnc#1120629] [bnc#1120630] [bnc#1120631]
+ [CVE-2018-20532] [CVE-2018-20533] [CVE-2018-20534]
+- no longer disable infarch rules when they don't conflict with
+ the job
+- do not autouninstall packages because of forcebest updates
+- bump version to 0.6.36
+
+-------------------------------------------------------------------
Thu Aug 9 17:09:41 CEST 2018 - mls@suse.de
- refactor arch handling
%bcond_with bz2
%bcond_with xz
%endif
-%if 0%{?sle_version} >= 150000 || 0%{?suse_version} >= 1500
+%if 0%{?is_opensuse} && ( 0%{?sle_version} >= 150000 || 0%{?suse_version} >= 1500 )
%bcond_without zstd
%else
%bcond_with zstd
if (MAPTST(&solv->multiversion, p))
break;
if (p)
- continue;
+ continue; /* found a multiversion package that will not obsolate anything */
}
om.size = 0;
Solvable *s;
Id p, pp;
+ if (!pool->installed)
+ return;
for (i = j = 0; i < plist->count; i++)
{
s = pool->solvables + plist->elements[i];
{
s = pool->solvables + plist->elements[i];
- POOL_DEBUG(SOLV_DEBUG_POLICY, "- %s[%s]\n",
- pool_solvable2str(pool, s),
- (pool->installed && s->repo == pool->installed) ? "installed" : "not installed");
+ POOL_DEBUG(SOLV_DEBUG_POLICY, "- %s [%d]%s\n",
+ pool_solvable2str(pool, s), plist->elements[i],
+ (pool->installed && s->repo == pool->installed) ? "I" : "");
if (!best) /* if no best yet, the current is best */
{
else
prune_obsoleted(pool, plist);
}
- if (plist->count > 1 && pool->installed)
- move_installed_to_front(pool, plist);
}
{
char kn[256];
Id p, pp, knid;
- memcpy(kn, "kernel", 8);
+ memcpy(kn, "kernel", 7);
memcpy(kn + 6, flavor, release - flavor + 1);
memcpy(kn + 6 + (release - flavor) + 1, sn, flavor - sn);
strcpy(kn + 6 + (release + 1 - sn), release);
#endif
dislike_old_versions(pool, plist);
sort_by_common_dep(pool, plist);
+ move_installed_to_front(pool, plist);
if (solv->urpmreorder)
urpm_reorder(solv, plist);
prefer_suggested(solv, plist);
{
dislike_old_versions(pool, plist);
sort_by_common_dep(pool, plist);
+ move_installed_to_front(pool, plist);
}
}
vprintf(format, args);
else
vfprintf(stderr, format, args);
+ va_end(args);
return;
}
vsnprintf(buf, sizeof(buf), format, args);
if (level > 2)
mask |= SOLV_DEBUG_PROPAGATE;
if (level > 3)
- mask |= SOLV_DEBUG_RULE_CREATION;
+ mask |= SOLV_DEBUG_RULE_CREATION | SOLV_DEBUG_WATCHES;
mask |= pool->debugmask & SOLV_DEBUG_TO_STDERR; /* keep bit */
pool->debugmask = mask;
}
#define SOLV_DEBUG_JOB (1<<11)
#define SOLV_DEBUG_SOLVER (1<<12)
#define SOLV_DEBUG_TRANSACTION (1<<13)
+#define SOLV_DEBUG_WATCHES (1<<14)
#define SOLV_DEBUG_TO_STDERR (1<<30)
if (v >= solv->updaterules && v < solv->updaterules_end)
{
Rule *r;
+ Id p = solv->installed->start + (v - solv->updaterules);
if (m && !MAPTST(m, v - solv->updaterules))
continue;
+ if (pool->considered && !MAPTST(pool->considered, p))
+ continue; /* do not uninstalled disabled packages */
+ if (solv->bestrules_pkg && solv->bestrules_end > solv->bestrules)
+ {
+ int j;
+ for (j = start + 1; j < solv->problems.count - 1; j++)
+ {
+ Id vv = solv->problems.elements[j];
+ if (vv >= solv->bestrules && vv < solv->bestrules_end && solv->bestrules_pkg[vv - solv->bestrules] == p)
+ break;
+ }
+ if (j < solv->problems.count - 1)
+ continue; /* best rule involved, do not uninstall */
+ }
/* check if identical to feature rule, we don't like that (except for orphans) */
r = solv->rules + solv->featurerules + (v - solv->updaterules);
if (!r->p)
if (solv->keep_orphans)
{
r = solv->rules + v;
- if (!r->d && !r->w2 && r->p == (solv->installed->start + (v - solv->updaterules)))
+ if (!r->d && !r->w2 && r->p == p)
{
lastfeature = v;
lastupdate = 0;
}
}
+/* check if multiversion solvable s2 has an obsoletes for installed solvable s */
+static int
+is_multiversion_obsoleteed(Pool *pool, Solvable *s, Solvable *s2)
+{
+ Id *wp, obs, *obsp;
+
+ if (pool->obsoleteusescolors && !pool_colormatch(pool, s, s2))
+ return 0;
+ obsp = s2->repo->idarraydata + s2->obsoletes;
+ if (!pool->obsoleteusesprovides)
+ {
+ while ((obs = *obsp++) != 0)
+ if (pool_match_nevr(pool, s, obs))
+ return 1;
+ }
+ else
+ {
+ while ((obs = *obsp++) != 0)
+ for (wp = pool_whatprovides_ptr(pool, obs); *wp; wp++)
+ if (pool->solvables + *wp == s)
+ return 1;
+ }
+ return 0;
+}
+
/*-------------------------------------------------------------------
*
* add rule for update
if (MAPTST(&solv->multiversion, qs.elements[i]))
{
Solvable *ps = pool->solvables + qs.elements[i];
- /* if keepexplicitobsoletes is set and the name is different,
- * we assume that there is an obsoletes. XXX: not 100% correct */
- if (solv->keepexplicitobsoletes && ps->name != s->name)
+ /* check if there is an explicit obsoletes */
+ if (solv->keepexplicitobsoletes && ps->obsoletes && is_multiversion_obsoleteed(pool, s, ps))
{
qs.elements[j++] = qs.elements[i];
continue;
if (pool->solvables[p].repo == installed)
return;
if (solv->multiversion.size && MAPTST(&solv->multiversion, p) && !solv->keepexplicitobsoletes)
- return;
+ return; /* will not obsolete anything, so just return */
}
omap.size = 0;
qstart = q->count;
revr = pool_str2id(pool, r, 1);
ret |= SELECTION_REL;
}
- if ((flags & SELECTION_GLOB) != 0 && !strpbrk(rname, "[*?") != 0)
+ if ((flags & SELECTION_GLOB) != 0 && strpbrk(rname, "[*?") == 0)
flags &= ~SELECTION_GLOB;
if ((flags & SELECTION_GLOB) == 0 && (flags & SELECTION_NOCASE) == 0 && (flags & SELECTION_MATCH_DEPSTR) == 0)
Id *decisionmap = solv->decisionmap;
Id *watches = solv->watches + pool->nsolvables; /* place ptr in middle */
- POOL_DEBUG(SOLV_DEBUG_PROPAGATE, "----- propagate -----\n");
+ POOL_DEBUG(SOLV_DEBUG_PROPAGATE, "----- propagate level %d -----\n", level);
/* foreach non-propagated decision */
while (solv->propagate_index < solv->decisionq.count)
IF_POOLDEBUG (SOLV_DEBUG_PROPAGATE)
{
- POOL_DEBUG(SOLV_DEBUG_PROPAGATE, "propagate for decision %d level %d\n", -pkg, level);
+ POOL_DEBUG(SOLV_DEBUG_PROPAGATE, "propagate decision %d:", -pkg);
solver_printruleelement(solv, SOLV_DEBUG_PROPAGATE, 0, -pkg);
}
continue;
}
- IF_POOLDEBUG (SOLV_DEBUG_PROPAGATE)
+ IF_POOLDEBUG (SOLV_DEBUG_WATCHES)
{
- POOL_DEBUG(SOLV_DEBUG_PROPAGATE," watch triggered ");
- solver_printrule(solv, SOLV_DEBUG_PROPAGATE, r);
+ POOL_DEBUG(SOLV_DEBUG_WATCHES, " watch triggered ");
+ solver_printrule(solv, SOLV_DEBUG_WATCHES, r);
}
/*
* if we found some p that is UNDEF or TRUE, move
* watch to it
*/
- IF_POOLDEBUG (SOLV_DEBUG_PROPAGATE)
+ IF_POOLDEBUG (SOLV_DEBUG_WATCHES)
{
if (p > 0)
- POOL_DEBUG(SOLV_DEBUG_PROPAGATE, " -> move w%d to %s\n", (pkg == r->w1 ? 1 : 2), pool_solvid2str(pool, p));
+ POOL_DEBUG(SOLV_DEBUG_WATCHES, " -> move w%d to %s\n", (pkg == r->w1 ? 1 : 2), pool_solvid2str(pool, p));
else
- POOL_DEBUG(SOLV_DEBUG_PROPAGATE, " -> move w%d to !%s\n", (pkg == r->w1 ? 1 : 2), pool_solvid2str(pool, -p));
+ POOL_DEBUG(SOLV_DEBUG_WATCHES, " -> move w%d to !%s\n", (pkg == r->w1 ? 1 : 2), pool_solvid2str(pool, -p));
}
*rp = *next_rp;
} /* while we have non-decided decisions */
- POOL_DEBUG(SOLV_DEBUG_PROPAGATE, "----- propagate end-----\n");
+ POOL_DEBUG(SOLV_DEBUG_PROPAGATE, "----- propagate end -----\n");
return 0; /* all is well */
}
return level;
}
+/* one or more installed cleandeps packages in dq that are to be updated */
+/* we need to emulate the code in resolve_installed */
+static void
+do_cleandeps_update_filter(Solver *solv, Queue *dq)
+{
+ Pool *pool = solv->pool;
+ Repo *installed = solv->installed;
+ Id *specialupdaters = solv->specialupdaters;
+ Id p, p2, pp, d;
+ Queue q;
+ int i, j, k;
+
+ queue_init(&q);
+ for (i = 0; i < dq->count; i++)
+ {
+ Id p = dq->elements[i];
+ if (p < 0)
+ p = -p;
+ if (pool->solvables[p].repo != installed || !MAPTST(&solv->cleandepsmap, p - installed->start))
+ continue;
+ queue_empty(&q);
+ /* find updaters */
+ if (specialupdaters && (d = specialupdaters[p - installed->start]) != 0)
+ {
+ while ((p2 = pool->whatprovidesdata[d++]) != 0)
+ if (solv->decisionmap[p2] >= 0)
+ queue_push(&q, p2);
+ }
+ else
+ {
+ Rule *r = solv->rules + solv->updaterules + (p - installed->start);
+ if (r->p)
+ {
+ FOR_RULELITERALS(p2, pp, r)
+ if (solv->decisionmap[p2] >= 0)
+ queue_push(&q, p2);
+ }
+ }
+ if (q.count && solv->update_targets && solv->update_targets->elements[p - installed->start])
+ prune_to_update_targets(solv, solv->update_targets->elements + solv->update_targets->elements[p - installed->start], &q);
+ /* mark all elements in dq that are in the updaters list */
+ dq->elements[i] = -p;
+ for (j = 0; j < dq->count; j++)
+ {
+ p = dq->elements[j];
+ if (p < 0)
+ continue;
+ for (k = 0; k < q.count; k++)
+ if (q.elements[k] == p)
+ {
+ dq->elements[j] = -p;
+ break;
+ }
+ }
+ }
+ /* now prune to marked elements */
+ for (i = j = 0; i < dq->count; i++)
+ if ((p = dq->elements[i]) < 0)
+ dq->elements[j++] = -p;
+ dq->count = j;
+ queue_free(&q);
+}
+
static int
resolve_dependencies(Solver *solv, int level, int disablerules, Queue *dq)
{
}
if (i == solv->nrules)
i = 1;
+ if (solv->focus_best && solv->do_extra_reordering && i >= solv->featurerules)
+ continue;
r = solv->rules + i;
if (r->d < 0) /* ignore disabled rules */
continue;
/* prune to cleandeps packages */
if (solv->cleandepsmap.size && solv->installed)
{
+ int cleandeps_update = 0;
Repo *installed = solv->installed;
for (j = 0; j < dq->count; j++)
if (pool->solvables[dq->elements[j]].repo == installed && MAPTST(&solv->cleandepsmap, dq->elements[j] - installed->start))
- break;
+ {
+ if (solv->updatemap_all || (solv->updatemap.size && MAPTST(&solv->updatemap, dq->elements[j] - installed->start)))
+ {
+ cleandeps_update = 1; /* cleandeps package is marked for update */
+ continue;
+ }
+ break;
+ }
if (j < dq->count)
{
dq->elements[0] = dq->elements[j];
queue_truncate(dq, 1);
}
+ else if (cleandeps_update)
+ do_cleandeps_update_filter(solv, dq); /* special update filter */
}
if (dq->count > 1 && postponed >= 0)
POOL_DEBUG(SOLV_DEBUG_STATS, "solver started\n");
POOL_DEBUG(SOLV_DEBUG_STATS, "dosplitprovides=%d, noupdateprovide=%d, noinfarchcheck=%d\n", solv->dosplitprovides, solv->noupdateprovide, solv->noinfarchcheck);
POOL_DEBUG(SOLV_DEBUG_STATS, "allowuninstall=%d, allowdowngrade=%d, allownamechange=%d, allowarchchange=%d, allowvendorchange=%d\n", solv->allowuninstall, solv->allowdowngrade, solv->allownamechange, solv->allowarchchange, solv->allowvendorchange);
+ POOL_DEBUG(SOLV_DEBUG_STATS, "dupallowdowngrade=%d, dupallownamechange=%d, dupallowarchchange=%d, dupallowvendorchange=%d\n", solv->dup_allowdowngrade, solv->dup_allownamechange, solv->dup_allowarchchange, solv->dup_allowvendorchange);
POOL_DEBUG(SOLV_DEBUG_STATS, "promoteepoch=%d, forbidselfconflicts=%d\n", pool->promoteepoch, pool->forbidselfconflicts);
POOL_DEBUG(SOLV_DEBUG_STATS, "obsoleteusesprovides=%d, implicitobsoleteusesprovides=%d, obsoleteusescolors=%d, implicitobsoleteusescolors=%d\n", pool->obsoleteusesprovides, pool->implicitobsoleteusesprovides, pool->obsoleteusescolors, pool->implicitobsoleteusescolors);
POOL_DEBUG(SOLV_DEBUG_STATS, "dontinstallrecommended=%d, addalreadyrecommended=%d\n", solv->dontinstallrecommended, solv->addalreadyrecommended);
name_s = s;
}
solver_addjobrule(solv, -p, 0, 0, i, weak);
+#ifdef ENABLE_LINKED_PKGS
+ if (solv->instbuddy && installed && s->repo == installed && solv->instbuddy[p - installed->start] > 1)
+ solver_addjobrule(solv, -solv->instbuddy[p - installed->start], 0, 0, i, weak);
+#endif
}
/* special case for "erase a specific solvable": we also
* erase all other solvables with that name, so that they
}
}
FOR_JOB_SELECT(p, pp, select, what)
- solver_addjobrule(solv, installed && pool->solvables[p].repo == installed ? p : -p, 0, 0, i, weak);
+ {
+ s = pool->solvables + p;
+ solver_addjobrule(solv, installed && s->repo == installed ? p : -p, 0, 0, i, weak);
+#ifdef ENABLE_LINKED_PKGS
+ if (solv->instbuddy && installed && s->repo == installed && solv->instbuddy[p - installed->start] > 1)
+ solver_addjobrule(solv, solv->instbuddy[p - installed->start], 0, 0, i, weak);
+#endif
+ }
break;
case SOLVER_DISTUPGRADE:
POOL_DEBUG(SOLV_DEBUG_JOB, "job: distupgrade %s\n", solver_select2str(pool, select, what));
void
stringpool_init_empty(Stringpool *ss)
{
- const char *emptystrs[] = {
- "<NULL>",
- "",
- 0,
- };
+ static const char *emptystrs[] = { "<NULL>", "", 0 };
stringpool_init(ss, emptystrs);
}
--- /dev/null
+repo system 0 testtags <inline>
+#>=Pkg: a 1 1 noarch
+#>=Con: b
+repo available 0 testtags <inline>
+#>=Pkg: b 1 1 noarch
+
+system x86_64 rpm system
+solverflags allowuninstall
+disable pkg a-1-1.noarch@system
+job install name b
+result transaction,problems <inline>
+#>problem a658cbaf info package a-1-1.noarch conflicts with b provided by b-1-1.noarch
+#>problem a658cbaf solution 567aa15d erase a-1-1.noarch@system
+#>problem a658cbaf solution e98e1a37 deljob install name b
--- /dev/null
+repo system 0 testtags <inline>
+#>=Pkg: a 1 1 noarch
+#>=Req: b = 1-1
+#>=Pkg: b 1 1 noarch
+repo available 0 testtags <inline>
+#>=Pkg: a 2 1 noarch
+#>=Req: b = 2-1
+#>=Pkg: b 2 1 noarch
+
+system x86_64 rpm system
+disable pkg b-1-1.noarch@system
+disable pkg b-2-1.noarch@available
+job allowuninstall pkg a-1-1.noarch@system
+job allowuninstall pkg b-1-1.noarch@system
+job update name a [forcebest]
+result transaction,problems <inline>
+#>problem e6d3911d info nothing provides b = 2-1 needed by a-2-1.noarch
+#>problem e6d3911d solution 0011b04f allow a-1-1.noarch@system
+#>problem e6d3911d solution 44d189a0 erase a-1-1.noarch@system
--- /dev/null
+repo system 0 testtags <inline>
+#>=Pkg: a 1 1 x86_64
+#>=Req: b
+#>=Pkg: b 1 1 x86_64
+repo available 0 testtags <inline>
+#>=Pkg: a 2 1 x86_64
+#>=Req: b
+#>=Pkg: b 2 1 x86_64
+#>=Pkg: c 2 1 x86_64
+#>=Prv: b = 4
+repo available2 0 testtags <inline>
+#>=Pkg: b 3 1 x86_64
+system x86_64 rpm system
+
+job update all packages [cleandeps]
+result transaction,problems <inline>
+#>upgrade a-1-1.x86_64@system a-2-1.x86_64@available
+#>upgrade b-1-1.x86_64@system b-3-1.x86_64@available2
+nextjob
+job update repo available [cleandeps]
+result transaction,problems <inline>
+#>upgrade a-1-1.x86_64@system a-2-1.x86_64@available
+#>upgrade b-1-1.x86_64@system b-2-1.x86_64@available
close(fds[1]);
}
if (recursive)
- execl("/usr/bin/find", ".", "-name", ".", "-o", "-name", ".*", "-prune", "-o", "-name", "*.delta.rpm", "-o", "-name", "*.patch.rpm", "-o", "-name", "*.rpm", "-a", "-type", "f", "-print0", (char *)0);
+ execl("/usr/bin/find", "/usr/bin/find", ".", "-name", ".", "-o", "-name", ".*", "-prune", "-o", "-name", "*.delta.rpm", "-o", "-name", "*.patch.rpm", "-o", "-name", "*.rpm", "-a", "-type", "f", "-print0", (char *)0);
else
- execl("/usr/bin/find", ".", "-maxdepth", "1", "-name", ".", "-o", "-name", ".*", "-prune", "-o", "-name", "*.delta.rpm", "-o", "-name", "*.patch.rpm", "-o", "-name", "*.rpm", "-a", "-type", "f", "-print0", (char *)0);
+ execl("/usr/bin/find", "/usr/bin/find", ".", "-maxdepth", "1", "-name", ".", "-o", "-name", ".*", "-prune", "-o", "-name", "*.delta.rpm", "-o", "-name", "*.patch.rpm", "-o", "-name", "*.rpm", "-a", "-type", "f", "-print0", (char *)0);
perror("/usr/bin/find");
_exit(1);
}
repodata_set_location(data, p, 0, 0, bp[0] == '.' && bp[1] == '/' ? bp + 2 : bp);
solv_free(rpm);
}
+ solv_free(buf);
fclose(fp);
while (waitpid(pid, &wstatus, 0) == -1)
{
filename = susetags_find(files, nfiles, "packages");
if (filename && (fp = susetags_open(ddir, filename, &tmp, 1)) != 0)
{
- if (repo_add_susetags(repo, fp, defvendor, 0, REPO_NO_INTERNALIZE|SUSETAGS_RECORD_SHARES))
+ if (repo_add_susetags(repo, fp, defvendor, 0, SUSETAGS_RECORD_SHARES))
{
fprintf(stderr, "%s: %s\n", tmp, pool_errstr(pool));
exit(1);
usage(int status)
{
fprintf(stderr, "\nUsage:\n"
- "rpmdb2solv [-n] [-b <basefile>] [-p <productsdir>] [-r <root>]\n"
+ "rpmdb2solv [-P] [-C] [-n] [-b <basefile>] [-p <productsdir>] [-r <root>]\n"
" -n : No packages, do not read rpmdb, useful to only parse products\n"
" -b <basefile> : Write .solv to <basefile>.solv instead of stdout\n"
" -p <productsdir> : Scan <productsdir> for .prod files, representing installed products\n"
" -r <root> : Prefix rpmdb path and <productsdir> with <root>\n"
" -o <solv> : Write .solv to file instead of stdout\n"
+ " -P : print percentage done\n"
+ " -C : include the changelog\n"
);
exit(status);
}
Repodata *data;
int c, percent = 0;
int nopacks = 0;
+ int add_changelog = 0;
const char *root = 0;
const char *basefile = 0;
const char *refname = 0;
* parse arguments
*/
- while ((c = getopt(argc, argv, "APhnkxXb:r:p:o:")) >= 0)
+ while ((c = getopt(argc, argv, "ACPhnkxXb:r:p:o:")) >= 0)
switch (c)
{
case 'h':
pubkeys = 1;
break;
#endif
+ case 'C':
+ add_changelog = 1;
+ break;
default:
usage(1);
}
if (!nopacks)
{
- if (repo_add_rpmdb_reffp(repo, reffp, REPO_USE_ROOTDIR | REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE | (percent ? RPMDB_REPORT_PROGRESS : 0)))
+ int flags = REPO_USE_ROOTDIR | REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE;
+ if (percent)
+ flags |= RPMDB_REPORT_PROGRESS;
+ if (add_changelog)
+ flags |= RPM_ADD_WITH_CHANGELOG;
+ if (repo_add_rpmdb_reffp(repo, reffp, flags))
{
fprintf(stderr, "rpmdb2solv: %s\n", pool_errstr(pool));
exit(1);
perror(fn);
exit(1);
}
- if (repo_add_susetags(repo, fp, defvendor, 0, flags | REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE))
+ if (repo_add_susetags(repo, fp, defvendor, 0, flags | REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE | SUSETAGS_RECORD_SHARES))
{
fprintf(stderr, "susetags2solv: %s: %s\n", fnp, pool_errstr(pool));
exit(1);