80
85
static void rpmalFreeIndex(rpmal al)
82
al->providesHash = rpmalProvidesHashFree(al->providesHash);
87
al->providesHash = rpmalDepHashFree(al->providesHash);
88
al->obsoletesHash = rpmalDepHashFree(al->obsoletesHash);
83
89
al->fileHash = rpmalFileHashFree(al->fileHash);
86
rpmal rpmalCreate(int delta, rpmtransFlags tsflags,
92
rpmal rpmalCreate(rpmstrPool pool, int delta, rpmtransFlags tsflags,
87
93
rpm_color_t tscolor, rpm_color_t prefcolor)
89
95
rpmal al = xcalloc(1, sizeof(*al));
97
/* transition time safe-guard */
100
al->pool = rpmstrPoolLink(pool);
91
101
al->delta = delta;
93
103
al->alloced = al->delta;
94
104
al->list = xmalloc(sizeof(*al->list) * al->alloced);;
96
106
al->providesHash = NULL;
107
al->obsoletesHash = NULL;
97
108
al->fileHash = NULL;
98
109
al->tsflags = tsflags;
99
110
al->tscolor = tscolor;
164
186
struct fileNameEntry_s fileName;
165
187
struct availableIndexEntry_s fileEntry;
188
int fc = rpmfiFC(fi);
167
189
rpm_color_t ficolor;
168
190
int skipdoc = (al->tsflags & RPMTRANS_FLAG_NODOCS);
169
191
int skipconf = (al->tsflags & RPMTRANS_FLAG_NOCONFIGS);
171
193
fileEntry.pkgNum = pkgNum;
173
fi = rpmfiInit(fi, 0);
174
while ((i = rpmfiNext(fi)) >= 0) {
195
for (int i = 0; i < fc; i++) {
175
196
/* Ignore colored provides not in our rainbow. */
176
ficolor = rpmfiFColor(fi);
197
ficolor = rpmfiFColorIndex(fi, i);
177
198
if (al->tscolor && ficolor && !(al->tscolor & ficolor))
180
201
/* Ignore files that wont be installed */
181
if (skipdoc && (rpmfiFFlags(fi) & RPMFILE_DOC))
202
if (skipdoc && (rpmfiFFlagsIndex(fi, i) & RPMFILE_DOC))
183
if (skipconf && (rpmfiFFlags(fi) & RPMFILE_CONFIG))
204
if (skipconf && (rpmfiFFlagsIndex(fi, i) & RPMFILE_CONFIG))
186
fileName.dirName = rpmfiDN(fi);
187
fileName.baseName = rpmfiBN(fi);
207
fileName.dirName = rpmfiDNIdIndex(fi, rpmfiDIIndex(fi, i));
208
fileName.baseName = rpmfiBNIdIndex(fi, i);
189
210
fileEntry.entryIx = i;
197
218
struct availableIndexEntry_s indexEntry;
198
219
rpm_color_t dscolor;
199
220
int skipconf = (al->tsflags & RPMTRANS_FLAG_NOCONFIGS);
221
int dc = rpmdsCount(provides);
201
223
indexEntry.pkgNum = pkgNum;
203
if (rpmdsInit(provides) != NULL)
204
while (rpmdsNext(provides) >= 0) {
225
for (int i = 0; i < dc; i++) {
205
226
/* Ignore colored provides not in our rainbow. */
206
dscolor = rpmdsColor(provides);
227
dscolor = rpmdsColorIndex(provides, i);
207
228
if (al->tscolor && dscolor && !(al->tscolor & dscolor))
210
231
/* Ignore config() provides if the files wont be installed */
211
if (skipconf & (rpmdsFlags(provides) & RPMSENSE_CONFIG))
232
if (skipconf & (rpmdsFlagsIndex(provides, i) & RPMSENSE_CONFIG))
214
indexEntry.entryIx = rpmdsIx(provides);
215
rpmalProvidesHashAddEntry(al->providesHash, rpmdsN(provides), indexEntry);
235
indexEntry.entryIx = i;;
236
rpmalDepHashAddEntry(al->providesHash,
237
rpmdsNIdIndex(provides, i), indexEntry);
241
static void rpmalAddObsoletes(rpmal al, rpmalNum pkgNum, rpmds obsoletes)
243
struct availableIndexEntry_s indexEntry;
245
int dc = rpmdsCount(obsoletes);
247
indexEntry.pkgNum = pkgNum;
249
for (int i = 0; i < dc; i++) {
250
/* Obsoletes shouldn't be colored but just in case... */
251
dscolor = rpmdsColorIndex(obsoletes, i);
252
if (al->tscolor && dscolor && !(al->tscolor & dscolor))
255
indexEntry.entryIx = i;;
256
rpmalDepHashAddEntry(al->obsoletesHash,
257
rpmdsNIdIndex(obsoletes, i), indexEntry);
234
276
alp->provides = rpmdsLink(rpmteDS(p, RPMTAG_PROVIDENAME));
277
alp->obsoletes = rpmdsLink(rpmteDS(p, RPMTAG_OBSOLETENAME));
235
278
alp->fi = rpmfiLink(rpmteFI(p));
237
if (al->providesHash != NULL) { // index is already created
281
* Transition-time safe-guard to catch private-pool uses.
282
* File sets with no files have NULL pool, that's fine. But WTF is up
283
* with the provides: every single package should have at least its
284
* own name as a provide, and thus never NULL, and normal use matches
285
* this expectation. However the test-suite is tripping up on NULL
286
* NULL pool from NULL alp->provides in numerous cases?
289
rpmstrPool fipool = rpmfiPool(alp->fi);
290
rpmstrPool dspool = rpmdsPool(alp->provides);
292
assert(fipool == NULL || fipool == al->pool);
293
assert(dspool == NULL || dspool == al->pool);
296
/* Try to be lazy as delayed hash creation is cheaper */
297
if (al->providesHash != NULL)
238
298
rpmalAddProvides(al, pkgNum, alp->provides);
299
if (al->obsoletesHash != NULL)
300
rpmalAddObsoletes(al, pkgNum, alp->obsoletes);
301
if (al->fileHash != NULL)
239
302
rpmalAddFiles(al, pkgNum, alp->fi);
242
304
assert(((rpmalNum)(alp - al->list)) == pkgNum);
245
static void rpmalMakeIndex(rpmal al)
307
static void rpmalMakeFileIndex(rpmal al)
247
309
availablePackage alp;
252
if (al == NULL || al->list == NULL) return;
253
if (al->providesHash != NULL || al->fileHash != NULL)
255
312
for (i = 0; i < al->size; i++) {
256
313
alp = al->list + i;
257
if (alp->provides != NULL)
258
providesCnt += rpmdsCount(alp->provides);
259
314
if (alp->fi != NULL)
260
315
fileCnt += rpmfiFC(alp->fi);
263
al->providesHash = rpmalProvidesHashCreate(providesCnt/4+128, rstrhash,
265
al->fileHash = rpmalFileHashCreate(fileCnt/4+128, fileHash, fileCompare,
317
al->fileHash = rpmalFileHashCreate(fileCnt/4+128,
318
fileHash, fileCompare, NULL, NULL);
319
for (i = 0; i < al->size; i++) {
321
rpmalAddFiles(al, i, alp->fi);
325
static void rpmalMakeProvidesIndex(rpmal al)
327
availablePackage alp;
328
int i, providesCnt = 0;
330
for (i = 0; i < al->size; i++) {
332
providesCnt += rpmdsCount(alp->provides);
335
al->providesHash = rpmalDepHashCreate(providesCnt/4+128,
336
sidHash, sidCmp, NULL, NULL);
268
337
for (i = 0; i < al->size; i++) {
269
338
alp = al->list + i;
270
339
rpmalAddProvides(al, i, alp->provides);
271
rpmalAddFiles(al, i, alp->fi);
275
static rpmte * rpmalAllFileSatisfiesDepend(const rpmal al, const rpmds ds)
277
const char *fileName = rpmdsN(ds);
343
static void rpmalMakeObsoletesIndex(rpmal al)
345
availablePackage alp;
346
int i, obsoletesCnt = 0;
348
for (i = 0; i < al->size; i++) {
350
obsoletesCnt += rpmdsCount(alp->obsoletes);
353
al->obsoletesHash = rpmalDepHashCreate(obsoletesCnt/4+128,
354
sidHash, sidCmp, NULL, NULL);
355
for (i = 0; i < al->size; i++) {
357
rpmalAddObsoletes(al, i, alp->obsoletes);
361
rpmte * rpmalAllObsoletes(rpmal al, rpmds ds)
365
availableIndexEntry result;
368
if (al == NULL || ds == NULL || (nameId = rpmdsNId(ds)) == 0)
371
if (al->obsoletesHash == NULL)
372
rpmalMakeObsoletesIndex(al);
374
rpmalDepHashGetEntry(al->obsoletesHash, nameId, &result, &resultCnt, NULL);
377
availablePackage alp;
380
ret = xmalloc((resultCnt+1) * sizeof(*ret));
382
for (int i = 0; i < resultCnt; i++) {
383
alp = al->list + result[i].pkgNum;
384
if (alp->p == NULL) // deleted
387
rc = rpmdsCompareIndex(alp->obsoletes, result[i].entryIx,
391
rpmdsNotify(ds, "(added obsolete)", 0);
406
static rpmte * rpmalAllFileSatisfiesDepend(const rpmal al, const char *fileName)
278
408
const char *slash;
279
409
rpmte * ret = NULL;
286
416
availableIndexEntry result;
287
417
int resultCnt = 0;
288
418
size_t bnStart = (slash - fileName) + 1;
289
char dirName[bnStart + 1];
290
struct fileNameEntry_s fne = {
291
.baseName = fileName + bnStart,
294
strncpy(dirName, fileName, bnStart);
295
dirName[bnStart] = '\0';
419
struct fileNameEntry_s fne;
421
fne.baseName = rpmstrPoolId(al->pool, fileName + bnStart, 0);
422
fne.dirName = rpmstrPoolIdn(al->pool, fileName, bnStart, 0);
424
if (al->fileHash == NULL)
425
rpmalMakeFileIndex(al);
297
427
rpmalFileHashGetEntry(al->fileHash, fne, &result, &resultCnt, NULL);
329
458
availablePackage alp;
332
if (al == NULL || ds == NULL || (name = rpmdsN(ds)) == NULL)
461
if (al == NULL || ds == NULL || (nameId = rpmdsNId(ds)) == 0)
335
if (al->providesHash == NULL && al->fileHash == NULL)
338
464
obsolete = (rpmdsTagN(ds) == RPMTAG_OBSOLETENAME);
465
name = rpmstrPoolStr(al->pool, nameId);
339
466
if (!obsolete && *name == '/') {
340
467
/* First, look for files "contained" in package ... */
341
ret = rpmalAllFileSatisfiesDepend(al, ds);
342
if (ret != NULL && *ret != NULL)
468
ret = rpmalAllFileSatisfiesDepend(al, name);
469
if (ret != NULL && *ret != NULL) {
470
rpmdsNotify(ds, "(added files)", 0);
344
473
/* ... then, look for files "provided" by package. */
345
474
ret = _free(ret);
348
rpmalProvidesHashGetEntry(al->providesHash, name, &result,
477
if (al->providesHash == NULL)
478
rpmalMakeProvidesIndex(al);
480
rpmalDepHashGetEntry(al->providesHash, nameId, &result,
349
481
&resultCnt, NULL);
351
483
if (resultCnt==0) return NULL;
356
488
alp = al->list + result[i].pkgNum;
357
489
if (alp->p == NULL) // deleted
359
(void) rpmdsSetIx(alp->provides, result[i].entryIx);
491
ix = result[i].entryIx;
361
493
/* Obsoletes are on package name, filter out other provide matches */
362
if (obsolete && !rstreq(rpmdsN(alp->provides), rpmteN(alp->p)))
494
if (obsolete && !rstreq(rpmdsNIndex(alp->provides, ix), rpmteN(alp->p)))
366
if (rpmdsIx(alp->provides) >= 0)
367
rc = rpmdsCompare(alp->provides, ds);
497
rc = rpmdsCompareIndex(alp->provides, ix, ds, rpmdsIx(ds));
370
500
rpmdsNotify(ds, "(added provide)", 0);