#include "chksum.h"
#include "repo_rpmdb.h"
#include "repo_solv.h"
+#ifdef ENABLE_COMPLEX_DEPS
+#include "pool_parserpmrichdep.h"
+#endif
/* 3: added triggers */
/* 4: fixed triggers */
/* 5: fixed checksum copying */
-#define RPMDB_COOKIE_VERSION 5
+/* 6: add SOLVABLE_PREREQ_IGNOREINST support */
+/* 7: fix bug in ignoreinst logic */
+#define RPMDB_COOKIE_VERSION 7
#define TAG_NAME 1000
#define TAG_VERSION 1001
repodata_set_str(repodata, handle, tag, str);
}
+static int
+ignq_sortcmp(const void *va, const void *vb, void *dp)
+{
+ int r = *(Id *)va - *(Id *)vb;
+ if (!r)
+ r = ((Id *)va)[1] - ((Id *)vb)[1];
+ return r;
+}
/*
* strong: 0: ignore strongness
* 2: filter to weak
*/
static unsigned int
-makedeps(Pool *pool, Repo *repo, RpmHead *rpmhead, int tagn, int tagv, int tagf, int flags)
+makedeps(Pool *pool, Repo *repo, RpmHead *rpmhead, int tagn, int tagv, int tagf, int flags, Queue *ignq)
{
char **n, **v;
unsigned int *f;
int i, cc, nc, vc, fc;
- int haspre, premask;
+ int haspre, premask, has_ign;
unsigned int olddeps;
Id *ida;
int strong = 0;
cc += haspre; /* add slot for the prereq marker */
olddeps = repo_reserve_ids(repo, 0, cc);
ida = repo->idarraydata + olddeps;
+
+ has_ign = 0;
for (i = 0; ; i++)
{
+ Id id;
if (i == nc)
{
if (haspre != 1)
if ((flags & RPM_ADD_NO_RPMLIBREQS) != 0)
if (!strncmp(n[i], "rpmlib(", 7))
continue;
+#ifdef ENABLE_COMPLEX_DEPS
+ if ((f[i] & (DEP_LESS|DEP_EQUAL|DEP_GREATER)) == 0 && n[i][0] == '(')
+ {
+ id = pool_parserpmrichdep(pool, n[i]);
+ if (id)
+ *ida++ = id;
+ else
+ cc--;
+ continue;
+ }
+#endif
+ id = pool_str2id(pool, n[i], 1);
if (f[i] & (DEP_LESS|DEP_GREATER|DEP_EQUAL))
{
- Id name, evr;
+ Id evr;
int fl = 0;
if ((f[i] & DEP_LESS) != 0)
fl |= REL_LT;
fl |= REL_EQ;
if ((f[i] & DEP_GREATER) != 0)
fl |= REL_GT;
- name = pool_str2id(pool, n[i], 1);
if (v[i][0] == '0' && v[i][1] == ':' && v[i][2])
evr = pool_str2id(pool, v[i] + 2, 1);
else
evr = pool_str2id(pool, v[i], 1);
- *ida++ = pool_rel2id(pool, name, evr, fl, 1);
+ id = pool_rel2id(pool, id, evr, fl, 1);
+ }
+ *ida++ = id;
+ if (haspre == 2 && ignq)
+ {
+ int is_ign = (f[i] & DEP_PRE_IN) != 0 && (f[i] & DEP_PRE_UN) == 0 ? 1 : 0;
+ has_ign |= is_ign;
+ queue_push2(ignq, id, is_ign);
}
- else
- *ida++ = pool_str2id(pool, n[i], 1);
}
*ida++ = 0;
repo->idarraysize += cc + 1;
solv_free(n);
solv_free(v);
solv_free(f);
+ if (ignq && ignq->count)
+ {
+ int j = 0;
+ if (has_ign && ignq->count == 2)
+ j = 1;
+ else if (has_ign)
+ {
+ Id id, lastid = 0;
+
+ solv_sort(ignq->elements, ignq->count / 2, sizeof(Id) * 2, ignq_sortcmp, 0);
+ for (i = j = 0; i < ignq->count; i += 2)
+ {
+ id = ignq->elements[i];
+ if (id != lastid && ignq->elements[i + 1] > 0)
+ ignq->elements[j++] = id;
+ lastid = id;
+ }
+ }
+ queue_truncate(ignq, j);
+ }
return olddeps;
}
char *name;
char *evr;
char *sourcerpm;
+ Queue ignq;
+ Id ignqbuf[64];
name = headstring(rpmhead, TAG_NAME);
if (!name)
s->evr = pool_str2id(pool, evr, 1);
s->vendor = pool_str2id(pool, headstring(rpmhead, TAG_VENDOR), 1);
- s->provides = makedeps(pool, repo, rpmhead, TAG_PROVIDENAME, TAG_PROVIDEVERSION, TAG_PROVIDEFLAGS, 0);
+ queue_init_buffer(&ignq, ignqbuf, sizeof(ignqbuf)/sizeof(*ignqbuf));
+
+ s->provides = makedeps(pool, repo, rpmhead, TAG_PROVIDENAME, TAG_PROVIDEVERSION, TAG_PROVIDEFLAGS, 0, 0);
if (s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
s->provides = repo_addid_dep(repo, s->provides, pool_rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
- s->requires = makedeps(pool, repo, rpmhead, TAG_REQUIRENAME, TAG_REQUIREVERSION, TAG_REQUIREFLAGS, flags);
- s->conflicts = makedeps(pool, repo, rpmhead, TAG_CONFLICTNAME, TAG_CONFLICTVERSION, TAG_CONFLICTFLAGS, 0);
- s->obsoletes = makedeps(pool, repo, rpmhead, TAG_OBSOLETENAME, TAG_OBSOLETEVERSION, TAG_OBSOLETEFLAGS, 0);
+ s->requires = makedeps(pool, repo, rpmhead, TAG_REQUIRENAME, TAG_REQUIREVERSION, TAG_REQUIREFLAGS, flags, &ignq);
+ s->conflicts = makedeps(pool, repo, rpmhead, TAG_CONFLICTNAME, TAG_CONFLICTVERSION, TAG_CONFLICTFLAGS, 0, 0);
+ s->obsoletes = makedeps(pool, repo, rpmhead, TAG_OBSOLETENAME, TAG_OBSOLETEVERSION, TAG_OBSOLETEFLAGS, 0, 0);
+
+ s->recommends = makedeps(pool, repo, rpmhead, TAG_RECOMMENDNAME, TAG_RECOMMENDVERSION, TAG_RECOMMENDFLAGS, 0, 0);
+ s->suggests = makedeps(pool, repo, rpmhead, TAG_SUGGESTNAME, TAG_SUGGESTVERSION, TAG_SUGGESTFLAGS, 0, 0);
+ s->supplements = makedeps(pool, repo, rpmhead, TAG_SUPPLEMENTNAME, TAG_SUPPLEMENTVERSION, TAG_SUPPLEMENTFLAGS, 0, 0);
+ s->enhances = makedeps(pool, repo, rpmhead, TAG_ENHANCENAME, TAG_ENHANCEVERSION, TAG_ENHANCEFLAGS, 0, 0);
- s->recommends = makedeps(pool, repo, rpmhead, TAG_RECOMMENDNAME, TAG_RECOMMENDVERSION, TAG_RECOMMENDFLAGS, 0);
- s->suggests = makedeps(pool, repo, rpmhead, TAG_SUGGESTNAME, TAG_SUGGESTVERSION, TAG_SUGGESTFLAGS, 0);
- s->supplements = makedeps(pool, repo, rpmhead, TAG_SUPPLEMENTNAME, TAG_SUPPLEMENTVERSION, TAG_SUPPLEMENTFLAGS, 0);
- s->enhances = makedeps(pool, repo, rpmhead, TAG_ENHANCENAME, TAG_ENHANCEVERSION, TAG_ENHANCEFLAGS, 0);
+ repo_rewrite_suse_deps(s, 0);
- s->supplements = repo_fix_supplements(repo, s->provides, s->supplements, 0);
- s->conflicts = repo_fix_conflicts(repo, s->conflicts);
+ if (data && ignq.count)
+ repodata_set_idarray(data, s - pool->solvables, SOLVABLE_PREREQ_IGNOREINST, &ignq);
+ queue_free(&ignq);
if (data)
{
repodata_set_sourcepkg(data, handle, sourcerpm);
if ((flags & RPM_ADD_TRIGGERS) != 0)
{
- Id id, lastid;
- unsigned int ida = makedeps(pool, repo, rpmhead, TAG_TRIGGERNAME, TAG_TRIGGERVERSION, TAG_TRIGGERFLAGS, 0);
-
- lastid = 0;
- for (; (id = repo->idarraydata[ida]) != 0; ida++)
- {
- /* we currently do not support rel ids in incore data, so
- * strip off versioning information */
- while (ISRELDEP(id))
- {
- Reldep *rd = GETRELDEP(pool, id);
- id = rd->name;
- }
- if (id == lastid)
- continue;
+ unsigned int ida = makedeps(pool, repo, rpmhead, TAG_TRIGGERNAME, TAG_TRIGGERVERSION, TAG_TRIGGERFLAGS, 0, 0);
+ Id id, lastid = 0;
+ for (lastid = 0; (id = repo->idarraydata[ida]) != 0; ida++, lastid = id)
+ if (id != lastid)
repodata_add_idarray(data, handle, SOLVABLE_TRIGGERS, id);
- lastid = id;
- }
}
if ((flags & RPM_ADD_NO_FILELIST) == 0)
addfilelist(data, handle, rpmhead, flags);
DB_ENV *dbenv; /* database environment */
DB *db; /* packages database */
int byteswapped; /* endianess of packages database */
+ int is_ostree; /* read-only db that lives in /usr/share/rpm */
};
struct rpmdbentry {
snprintf(dbpath, PATH_MAX, "%s/var/lib/rpm", rootdir ? rootdir : "");
if (access(dbpath, W_OK) == -1)
{
+ snprintf(dbpath, PATH_MAX, "%s/usr/share/rpm/Packages", rootdir ? rootdir : "");
+ if (access(dbpath, R_OK) == 0)
+ state->is_ostree = 1;
+ snprintf(dbpath, PATH_MAX, "%s%s", rootdir ? rootdir : "", state->is_ostree ? "/usr/share/rpm" : "/var/lib/rpm");
r = dbenv->open(dbenv, dbpath, DB_CREATE|DB_PRIVATE|DB_INIT_MPOOL, 0);
}
else
/* close down */
if (!state)
return;
- if (state->rootdir)
- solv_free(state->rootdir);
if (state->db)
state->db->close(state->db, 0);
if (state->dbenv)
closedbenv(state);
+ if (state->rootdir)
+ solv_free(state->rootdir);
solv_free(state->rpmhead);
}
DBT dbkey;
DBT dbdata;
- snprintf(dbpath, PATH_MAX, "%s/var/lib/rpm/Name", state->rootdir ? state->rootdir : "");
+ snprintf(dbpath, PATH_MAX, "%s%s/Name", state->rootdir ? state->rootdir : "", state->is_ostree ? "/usr/share/rpm" : "/var/lib/rpm");
if (stat(dbpath, &statbuf))
return 0;
memset(&dbkey, 0, sizeof(dbkey));
cbdata->handle = repodata_new_handle(data);
repodata_add_flexarray(data, cbdata->subhandle, keyname, cbdata->handle);
break;
- case REPOKEY_TYPE_MD5:
- case REPOKEY_TYPE_SHA1:
- case REPOKEY_TYPE_SHA256:
- repodata_set_bin_checksum(data, handle, keyname, key->type, (const unsigned char *)kv->str);
- break;
default:
+ if (solv_chksum_len(key->type))
+ {
+ repodata_set_bin_checksum(data, handle, keyname, key->type, (const unsigned char *)kv->str);
+ break;
+ }
break;
}
return 0;
}
/* XXX: should get ro lock of Packages database! */
- snprintf(dbpath, PATH_MAX, "%s/var/lib/rpm/Packages", state.rootdir ? state.rootdir : "");
+ snprintf(dbpath, PATH_MAX, "%s%s/Packages", state.rootdir ? state.rootdir : "", state.is_ostree ? "/usr/share/rpm" : "/var/lib/rpm");
if (stat(dbpath, &packagesstat))
{
pool_error(pool, -1, "%s: %s", dbpath, strerror(errno));
if ((flags & RPM_ITERATE_FILELIST_WITHCOL) != 0)
{
co = headint32array(rpmhead, TAG_FILECOLORS, &cnt2);
- if (!co || cnt != cnt2)
+ if (co && cnt != cnt2)
{
solv_free(co);
solv_free(md);
info.digest = md5;
}
}
- if (co)
- info.color = co[i];
+ info.color = co ? co[i] : 0;
(*cb)(cbdata, space, &info);
}
solv_free(space);