Add a new pseudo index for actually installed files
authorPanu Matilainen <pmatilai@redhat.com>
Mon, 29 Aug 2011 12:43:15 +0000 (15:43 +0300)
committerPanu Matilainen <pmatilai@redhat.com>
Mon, 29 Aug 2011 12:52:16 +0000 (15:52 +0300)
- RPMDBI_BASENAMES (ugh) returns all headers with matching filenames,
  whether the files are actually installed or not, which can be
  rather misleading when dealing with file dependencies. The new
  RPMDBI_INSTFILENAMES only returns headers with matching filenames
  whose state indicates they are actually present on the system.

lib/rpmdb.c
lib/rpmtag.h
python/rpmmodule.c

index 827cc1e..41c7603 100644 (file)
@@ -886,11 +886,12 @@ static Header rpmdbGetHeaderAt(rpmdb db, unsigned int offset)
  * @param db           rpm database
  * @param dbi          index database handle (always RPMDBI_BASENAMES)
  * @param filespec
+ * @param usestate     take file state into account?
  * @retval matches
  * @return             0 on success, 1 on not found, -2 on error
  */
 static int rpmdbFindByFile(rpmdb db, dbiIndex dbi, const char *filespec,
-                          dbiIndexSet * matches)
+                          int usestate, dbiIndexSet * matches)
 {
     char * dirName = NULL;
     const char * baseName;
@@ -925,7 +926,7 @@ static int rpmdbFindByFile(rpmdb db, dbiIndex dbi, const char *filespec,
 
     i = 0;
     while (i < allMatches->count) {
-       struct rpmtd_s bn, dn, di;
+       struct rpmtd_s bn, dn, di, fs;
        const char ** baseNames, ** dirNames;
        uint32_t * dirIndexes;
        unsigned int offset = dbiIndexRecordOffset(allMatches, i);
@@ -943,18 +944,32 @@ static int rpmdbFindByFile(rpmdb db, dbiIndex dbi, const char *filespec,
        baseNames = bn.data;
        dirNames = dn.data;
        dirIndexes = di.data;
+       if (usestate)
+           headerGet(h, RPMTAG_FILESTATES, &fs, HEADERGET_MINMEM);
 
        do {
            fingerPrint fp2;
            int num = dbiIndexRecordFileNumber(allMatches, i);
+           int skip = 0;
 
-           fp2 = fpLookup(fpc, dirNames[dirIndexes[num]], baseNames[num], 1);
-           if (FP_EQUAL(fp1, fp2)) {
-               struct dbiIndexItem rec = { 
-                   .hdrNum = dbiIndexRecordOffset(allMatches, i),
-                   .tagNum = dbiIndexRecordFileNumber(allMatches, i),
-               };
-               dbiAppendSet(*matches, &rec, 1, sizeof(rec), 0);
+           if (usestate) {
+               rpmtdSetIndex(&fs, num);
+               int s = rpmtdGetNumber(&fs); 
+               if (s != RPMFILE_STATE_NORMAL && s != RPMFILE_STATE_NETSHARED) {
+                   skip = 1;
+               }
+           }
+
+           if (!skip) {
+               fp2 = fpLookup(fpc, dirNames[dirIndexes[num]],
+                                   baseNames[num], 1);
+               if (FP_EQUAL(fp1, fp2)) {
+                   struct dbiIndexItem rec = { 
+                       .hdrNum = dbiIndexRecordOffset(allMatches, i),
+                       .tagNum = dbiIndexRecordFileNumber(allMatches, i),
+                   };
+                   dbiAppendSet(*matches, &rec, 1, sizeof(rec), 0);
+               }
            }
 
            prevoff = offset;
@@ -966,6 +981,8 @@ static int rpmdbFindByFile(rpmdb db, dbiIndex dbi, const char *filespec,
        rpmtdFreeData(&bn);
        rpmtdFreeData(&dn);
        rpmtdFreeData(&di);
+       if (usestate)
+           rpmtdFreeData(&fs);
        headerFree(h);
     }
 
@@ -1958,6 +1975,8 @@ rpmdbMatchIterator rpmdbInitIterator(rpmdb db, rpmDbiTagVal rpmtag,
     /* Fixup the physical index for our pseudo indexes */
     if (rpmtag == RPMDBI_LABEL) {
        dbtag = RPMDBI_NAME;
+    } else if (rpmtag == RPMDBI_INSTFILENAMES) {
+       dbtag = RPMDBI_BASENAMES;
     }
 
     dbi = rpmdbOpenIndex(db, dbtag, 0);
@@ -1976,7 +1995,9 @@ rpmdbMatchIterator rpmdbInitIterator(rpmdb db, rpmDbiTagVal rpmtag,
             if (rpmtag == RPMDBI_LABEL) {
                 rc = dbiFindByLabel(db, dbi, keyp, &set);
             } else if (rpmtag == RPMDBI_BASENAMES) {
-                rc = rpmdbFindByFile(db, dbi, keyp, &set);
+                rc = rpmdbFindByFile(db, dbi, keyp, 0, &set);
+            } else if (rpmtag == RPMDBI_INSTFILENAMES) {
+                rc = rpmdbFindByFile(db, dbi, keyp, 1, &set);
             } else {
                rc = dbiGetToSet(dbi, keyp, keylen, &set);
            }
index 3bcec0a..775d414 100644 (file)
@@ -313,6 +313,7 @@ typedef enum rpmTag_e {
 typedef enum rpmDbiTag_e {
     RPMDBI_PACKAGES            = 0,    /* Installed package headers. */
     RPMDBI_LABEL               = 2,    /* NEVRA label pseudo index */
+    RPMDBI_INSTFILENAMES       = 32,   /* Files with inst. state pseudo idx */
     RPMDBI_NAME                        = RPMTAG_NAME,
     RPMDBI_BASENAMES           = RPMTAG_BASENAMES,
     RPMDBI_GROUP               = RPMTAG_GROUP,
index 2f9e859..d3e664a 100644 (file)
@@ -480,6 +480,7 @@ static int initModule(PyObject *m)
 
     REGISTER_ENUM(RPMDBI_PACKAGES);
     REGISTER_ENUM(RPMDBI_LABEL);
+    REGISTER_ENUM(RPMDBI_INSTFILENAMES);
     REGISTER_ENUM(RPMDBI_NAME);
     REGISTER_ENUM(RPMDBI_BASENAMES);
     REGISTER_ENUM(RPMDBI_GROUP);