The following commit has been merged in the master branch:
commit c43931e799d36275cf6d44be94c63512b94b1c9e
Author: Guillem Jover <guil...@debian.org>
Date:   Tue Jun 22 10:57:47 2010 +0200

    dpkg: Use iterators instead of exposing packageslump directly

diff --git a/TODO b/TODO
index 86ba627..ffaa013 100644
--- a/TODO
+++ b/TODO
@@ -45,7 +45,6 @@ TODO
    - Use internerr instead of assert, and print more meaninful messages.
    - Make actionfunction return int, and avoid global exitcode variables.
    - Move ACTION and OBSOLETE, etc to ‘myopt.h’.
-   - Refactor packageslump into generic code.
    - Replace raw write and read calls with safe variants (signals etc).
    - Make deb build version a version instead of doing checks over a string.
    - Use enums for currently hardcoded literals (tdus, dependtry, etc).
diff --git a/src/archives.c b/src/archives.c
index 8a90ba6..ac268bb 100644
--- a/src/archives.c
+++ b/src/archives.c
@@ -107,9 +107,8 @@ filesavespackage(struct fileinlist *file,
                  struct pkginfo *pkgtobesaved,
                  struct pkginfo *pkgbeinginstalled)
 {
+  struct filepackages_iterator *iter;
   struct pkginfo *divpkg, *thirdpkg;
-  struct filepackages *packageslump;
-  int i;
   
   debug(dbg_eachfiledetail,"filesavespackage file `%s' package %s",
         file->namenode->name,pkgtobesaved->name);
@@ -139,31 +138,31 @@ filesavespackage(struct fileinlist *file,
   /* Look for a 3rd package which can take over the file (in case
    * it's a directory which is shared by many packages.
    */
-  for (packageslump= file->namenode->packages;
-       packageslump;
-       packageslump= packageslump->more) {
-    for (i=0; i < PERFILEPACKAGESLUMP && packageslump->pkgs[i]; i++) {
-      thirdpkg= packageslump->pkgs[i];
-      debug(dbg_eachfiledetail, "filesavespackage ... also in %s",
-            thirdpkg->name);
-      /* Is this not the package being installed or the one being
-       * checked for disappearance ?
-       */
-      if (thirdpkg == pkgbeinginstalled || thirdpkg == pkgtobesaved) continue;
-      /* If !fileslistvalid then we've already disappeared this one, so
-       * we shouldn't try to make it take over this shared directory.
-       */
-      debug(dbg_eachfiledetail,"filesavespackage ...  is 3rd package");
+  iter = filepackages_iter_new(file->namenode);
+  while ((thirdpkg = filepackages_iter_next(iter))) {
+    debug(dbg_eachfiledetail, "filesavespackage ... also in %s",
+          thirdpkg->name);
+
+    /* Is this not the package being installed or the one being
+     * checked for disappearance? */
+    if (thirdpkg == pkgbeinginstalled || thirdpkg == pkgtobesaved)
+      continue;
 
-      if (!thirdpkg->clientdata->fileslistvalid) {
-        debug(dbg_eachfiledetail, "process_archive ... already disappeared!");
-        continue;
-      }
-      /* We've found a package that can take this file. */
-      debug(dbg_eachfiledetail, "filesavespackage ...  taken -- no save");
-      return false;
+    /* If !fileslistvalid then we've already disappeared this one, so
+     * we shouldn't try to make it take over this shared directory. */
+    debug(dbg_eachfiledetail,"filesavespackage ...  is 3rd package");
+
+    if (!thirdpkg->clientdata->fileslistvalid) {
+      debug(dbg_eachfiledetail, "process_archive ... already disappeared!");
+      continue;
     }
+
+    /* We've found a package that can take this file. */
+    debug(dbg_eachfiledetail, "filesavespackage ...  taken -- no save");
+    return false;
   }
+  filepackages_iter_free(iter);
+
   debug(dbg_eachfiledetail, "filesavespackage ... not taken -- save !");
   return true;
 }
@@ -405,13 +404,12 @@ int tarobject(struct TarInfo *ti) {
   struct conffile *conff;
   struct tarcontext *tc= (struct tarcontext*)ti->UserData;
   bool existingdirectory, keepexisting;
-  int statr, i;
+  int statr;
   ssize_t r;
   struct stat stab, stabtmp;
   char databuf[TARBLKSZ];
   struct fileinlist *nifd, **oldnifd;
   struct pkginfo *divpkg, *otherpkg;
-  struct filepackages *packageslump;
   mode_t am;
 
   ensureobstackinit();
@@ -526,96 +524,100 @@ int tarobject(struct TarInfo *ti) {
 
   keepexisting = false;
   if (!existingdirectory) {
-    for (packageslump= nifd->namenode->packages;
-         packageslump;
-         packageslump= packageslump->more) {
-      for (i=0; i < PERFILEPACKAGESLUMP && packageslump->pkgs[i]; i++) {
-        otherpkg= packageslump->pkgs[i];
-        if (otherpkg == tc->pkg) continue;
-        debug(dbg_eachfile, "tarobject ... found in %s",otherpkg->name);
-        if (nifd->namenode->divert && nifd->namenode->divert->useinstead) {
-          /* Right, so we may be diverting this file.  This makes the conflict
-           * OK iff one of us is the diverting package (we don't need to
-           * check for both being the diverting package, obviously).
-           */
-          divpkg= nifd->namenode->divert->pkg;
-          debug(dbg_eachfile, "tarobject ... diverted, divpkg=%s",
-                divpkg ? divpkg->name : "<none>");
-          if (otherpkg == divpkg || tc->pkg == divpkg) continue;
+    struct filepackages_iterator *iter;
+
+    iter = filepackages_iter_new(nifd->namenode);
+    while ((otherpkg = filepackages_iter_next(iter))) {
+      if (otherpkg == tc->pkg)
+        continue;
+      debug(dbg_eachfile, "tarobject ... found in %s", otherpkg->name);
+
+      if (nifd->namenode->divert && nifd->namenode->divert->useinstead) {
+        /* Right, so we may be diverting this file. This makes the conflict
+         * OK iff one of us is the diverting package (we don't need to
+         * check for both being the diverting package, obviously). */
+        divpkg = nifd->namenode->divert->pkg;
+        debug(dbg_eachfile, "tarobject ... diverted, divpkg=%s",
+              divpkg ? divpkg->name : "<none>");
+        if (otherpkg == divpkg || tc->pkg == divpkg)
+          continue;
+      }
+
+      /* Nope ?  Hmm, file conflict, perhaps.  Check Replaces. */
+      switch (otherpkg->clientdata->replacingfilesandsaid) {
+      case 2:
+        keepexisting = true;
+      case 1:
+        continue;
+      }
+
+      /* Is the package with the conflicting file in the “config files only”
+       * state? If so it must be a config file and we can silenty take it
+       * over. */
+      if (otherpkg->status == stat_configfiles)
+        continue;
+
+      /* Perhaps we're removing a conflicting package? */
+      if (otherpkg->clientdata->istobe == itb_remove)
+        continue;
+
+      /* Is the file an obsolete conffile in the other package
+       * and a conffile in the new package? */
+      if ((nifd->namenode->flags & fnnf_new_conff) &&
+          !statr && S_ISREG(stab.st_mode)) {
+        for (conff = otherpkg->installed.conffiles;
+             conff;
+             conff = conff->next) {
+          if (!conff->obsolete)
+            continue;
+          if (stat(conff->name, &stabtmp))
+            if (errno == ENOENT || errno == ENOTDIR || errno == ELOOP)
+              continue;
+            if (stabtmp.st_dev == stab.st_dev &&
+                stabtmp.st_ino == stab.st_ino)
+              break;
         }
-        /* Nope ?  Hmm, file conflict, perhaps.  Check Replaces. */
-       switch (otherpkg->clientdata->replacingfilesandsaid) {
-       case 2:
-         keepexisting = true;
-       case 1:
-         continue;
-       }
-        /* Is the package with the conflicting file in the `config files
-         * only' state ?  If so it must be a config file and we can
-         * silenty take it over.
-         */
-        if (otherpkg->status == stat_configfiles) continue;
-        /* Perhaps we're removing a conflicting package ? */
-        if (otherpkg->clientdata->istobe == itb_remove) continue;
-
-       /* Is the file an obsolete conffile in the other package
-        * and a conffile in the new package ? */
-       if ((nifd->namenode->flags & fnnf_new_conff) &&
-           !statr && S_ISREG(stab.st_mode)) {
-         for (conff= otherpkg->installed.conffiles;
-              conff;
-              conff= conff->next) {
-           if (!conff->obsolete)
-             continue;
-           if (stat(conff->name, &stabtmp))
-             if (errno == ENOENT || errno == ENOTDIR || errno == ELOOP)
-               continue;
-           if (stabtmp.st_dev == stab.st_dev &&
-               stabtmp.st_ino == stab.st_ino)
-             break;
-         }
-         if (conff) {
-           debug(dbg_eachfiledetail,"tarobject other's obsolete conffile");
-           /* processarc.c will have copied its hash already. */
-           continue;
-         }
-       }
-
-        if (does_replace(tc->pkg, &tc->pkg->available,
-                         otherpkg, &otherpkg->installed)) {
-          printf(_("Replacing files in old package %s ...\n"),otherpkg->name);
-          otherpkg->clientdata->replacingfilesandsaid= 1;
-        } else if (does_replace(otherpkg, &otherpkg->installed,
-                                tc->pkg, &tc->pkg->available)) {
-         printf(_("Replaced by files in installed package %s ...\n"),
-                otherpkg->name);
-          otherpkg->clientdata->replacingfilesandsaid= 2;
-          nifd->namenode->flags &= ~fnnf_new_inarchive;
-         keepexisting = true;
+        if (conff) {
+          debug(dbg_eachfiledetail, "tarobject other's obsolete conffile");
+          /* processarc.c will have copied its hash already. */
+          continue;
+        }
+      }
+
+      if (does_replace(tc->pkg, &tc->pkg->available,
+                       otherpkg, &otherpkg->installed)) {
+        printf(_("Replacing files in old package %s ...\n"),otherpkg->name);
+        otherpkg->clientdata->replacingfilesandsaid = 1;
+      } else if (does_replace(otherpkg, &otherpkg->installed,
+                              tc->pkg, &tc->pkg->available)) {
+        printf(_("Replaced by files in installed package %s ...\n"),
+               otherpkg->name);
+        otherpkg->clientdata->replacingfilesandsaid = 2;
+        nifd->namenode->flags &= ~fnnf_new_inarchive;
+        keepexisting = true;
+      } else {
+        if (!statr && S_ISDIR(stab.st_mode)) {
+          forcibleerr(fc_overwritedir,
+                      _("trying to overwrite directory '%.250s' "
+                        "in package %.250s %.250s with nondirectory"),
+                      nifd->namenode->name, otherpkg->name,
+                      versiondescribe(&otherpkg->installed.version,
+                                      vdew_nonambig));
         } else {
-          if (!statr && S_ISDIR(stab.st_mode)) {
-            forcibleerr(fc_overwritedir,
-                        _("trying to overwrite directory '%.250s' "
-                          "in package %.250s %.250s with nondirectory"),
+          /* WTA: At this point we are replacing something without a Replaces.
+           * if the new object is a directory and the previous object does not
+           * exist assume it's also a directory and don't complain. */
+          if (!(statr && ti->Type == Directory))
+            forcibleerr(fc_overwrite,
+                        _("trying to overwrite '%.250s', "
+                          "which is also in package %.250s %.250s"),
                         nifd->namenode->name, otherpkg->name,
                         versiondescribe(&otherpkg->installed.version,
                                         vdew_nonambig));
-          } else {
-            /* WTA: At this point we are replacing something without a 
Replaces.
-            * if the new object is a directory and the previous object does not
-            * exist assume it's also a directory and don't complain
-            */
-            if (! (statr && ti->Type==Directory))
-              forcibleerr(fc_overwrite,
-                          _("trying to overwrite '%.250s', "
-                            "which is also in package %.250s %.250s"),
-                          nifd->namenode->name, otherpkg->name,
-                          versiondescribe(&otherpkg->installed.version,
-                                          vdew_nonambig));
-          }
         }
       }
     }
+    filepackages_iter_free(iter);
   }
 
   if (keepexisting) {
diff --git a/src/filesdb.c b/src/filesdb.c
index 1c07ea1..73f53e3 100644
--- a/src/filesdb.c
+++ b/src/filesdb.c
@@ -51,6 +51,62 @@
 #include "filesdb.h"
 #include "main.h"
 
+
+/* filepackages support for tracking packages owning a file. */
+
+#define PERFILEPACKAGESLUMP 10
+
+struct filepackages {
+  struct filepackages *more;
+
+  /* pkgs is a NULL-pointer-terminated list; anything after the first NULL
+   * is garbage. */
+  struct pkginfo *pkgs[PERFILEPACKAGESLUMP];
+};
+
+struct filepackages_iterator {
+  struct filepackages *pkg_lump;
+  int pkg_idx;
+};
+
+struct filepackages_iterator *
+filepackages_iter_new(struct filenamenode *fnn)
+{
+  struct filepackages_iterator *iter;
+
+  iter = m_malloc(sizeof(*iter));
+  iter->pkg_lump  = fnn->packages;
+  iter->pkg_idx = 0;
+
+  return iter;
+}
+
+struct pkginfo *
+filepackages_iter_next(struct filepackages_iterator *iter)
+{
+  struct pkginfo *pkg;
+
+  while (iter->pkg_lump) {
+    pkg = iter->pkg_lump->pkgs[iter->pkg_idx];
+
+    if (iter->pkg_idx < PERFILEPACKAGESLUMP && pkg) {
+      iter->pkg_idx++;
+      return pkg;
+    } else {
+      iter->pkg_lump = iter->pkg_lump->more;
+      iter->pkg_idx = 0;
+    }
+  }
+
+  return NULL;
+}
+
+void
+filepackages_iter_free(struct filepackages_iterator *iter)
+{
+  free(iter);
+}
+
 /*** Generic data structures and routines ***/
 
 static bool allpackagesdone = false;
diff --git a/src/filesdb.h b/src/filesdb.h
index 604e54e..7d2645c 100644
--- a/src/filesdb.h
+++ b/src/filesdb.h
@@ -120,15 +120,10 @@ struct diversion {
   /* The `contested' halves are in this list for easy cleanup. */
 };
 
-#define PERFILEPACKAGESLUMP 10
-
-struct filepackages {
-  struct filepackages *more;
-  struct pkginfo *pkgs[PERFILEPACKAGESLUMP];
-  /* pkgs is a null-pointer-terminated list; anything after the first null
-   * is garbage
-   */
-};
+struct filepackages_iterator;
+struct filepackages_iterator *filepackages_iter_new(struct filenamenode *fnn);
+struct pkginfo *filepackages_iter_next(struct filepackages_iterator *i);
+void filepackages_iter_free(struct filepackages_iterator *i);
 
 void filesdbinit(void);
 
diff --git a/src/help.c b/src/help.c
index c174841..a328f0e 100644
--- a/src/help.c
+++ b/src/help.c
@@ -492,21 +492,22 @@ hasdirectoryconffiles(struct filenamenode *file, struct 
pkginfo *pkg)
 bool
 isdirectoryinuse(struct filenamenode *file, struct pkginfo *pkg)
 {
-  struct filepackages *packageslump;
-  int i;
+  struct filepackages_iterator *iter;
+  struct pkginfo *other_pkg;
     
   debug(dbg_veryverbose, "isdirectoryinuse `%s' (except %s)", file->name,
         pkg ? pkg->name : "<none>");
-  for (packageslump= file->packages; packageslump; packageslump= 
packageslump->more) {
-    debug(dbg_veryverbose, "isdirectoryinuse packageslump %s ...",
-          packageslump->pkgs[0] ? packageslump->pkgs[0]->name : "<none>");
-    for (i=0; i < PERFILEPACKAGESLUMP && packageslump->pkgs[i]; i++) {
-      debug(dbg_veryverbose, "isdirectoryinuse considering [%d] %s ...", i,
-            packageslump->pkgs[i]->name);
-      if (packageslump->pkgs[i] == pkg) continue;
-      return true;
-    }
+
+  iter = filepackages_iter_new(file);
+  while ((other_pkg = filepackages_iter_next(iter))) {
+    debug(dbg_veryverbose, "isdirectoryinuse considering %s ...",
+          other_pkg->name);
+    if (other_pkg == pkg)
+      continue;
+    return true;
   }
+  filepackages_iter_free(iter);
+
   debug(dbg_veryverbose, "isdirectoryinuse no");
   return false;
 }
diff --git a/src/processarc.c b/src/processarc.c
index 3da1e0e..5b488ff 100644
--- a/src/processarc.c
+++ b/src/processarc.c
@@ -113,7 +113,6 @@ void process_archive(const char *filename) {
   struct fileinlist *cfile;
   struct reversefilelistiter rlistit;
   struct conffile *searchconff, **iconffileslastp, *newiconff;
-  struct filepackages *packageslump;
   struct dependency *dsearch, *newdeplist, **newdeplistlastp;
   struct dependency *newdep, *dep, *providecheck;
   struct deppossi *psearch, **newpossilastp, *possi, *newpossi, *pdep;
@@ -366,6 +365,8 @@ void process_archive(const char *filename) {
   if (conff) {
     push_cleanup(cu_closefile, ehflag_bombout, NULL, 0, 1, (void *)conff);
     while (fgets(conffilenamebuf,MAXCONFFILENAME-2,conff)) {
+      struct filepackages_iterator *iter;
+
       p= conffilenamebuf + strlen(conffilenamebuf);
       assert(p != conffilenamebuf);
       if (p[-1] != '\n')
@@ -390,29 +391,30 @@ void process_archive(const char *filename) {
        * the file we pick one at random.
        */
       searchconff = NULL;
-      for (packageslump= newconff->namenode->packages;
-           packageslump;
-           packageslump= packageslump->more) {
-        for (i=0; i < PERFILEPACKAGESLUMP && packageslump->pkgs[i]; i++) {
-          otherpkg= packageslump->pkgs[i];
-          debug(dbg_conffdetail,"process_archive conffile `%s' in package %s - 
conff ?",
-                newconff->namenode->name,otherpkg->name);
-          for (searchconff= otherpkg->installed.conffiles;
-               searchconff && 
strcmp(newconff->namenode->name,searchconff->name);
-               searchconff= searchconff->next)
-            debug(dbg_conffdetail,
-                  "process_archive conffile `%s' in package %s - conff ? not 
`%s'",
-                  newconff->namenode->name,otherpkg->name,searchconff->name);
-          if (searchconff) {
-            debug(dbg_conff,"process_archive conffile `%s' package=%s %s 
hash=%s",
-                  newconff->namenode->name,otherpkg->name,
-                  otherpkg == pkg ? "same" : "different!",
-                  searchconff->hash);
-            if (otherpkg == pkg) goto xit_conff_hashcopy_srch;
-          }
+
+      iter = filepackages_iter_new(newconff->namenode);
+      while ((otherpkg = filepackages_iter_next(iter))) {
+        debug(dbg_conffdetail,
+              "process_archive conffile `%s' in package %s - conff ?",
+              newconff->namenode->name, otherpkg->name);
+        for (searchconff = otherpkg->installed.conffiles;
+             searchconff && strcmp(newconff->namenode->name, 
searchconff->name);
+             searchconff = searchconff->next)
+          debug(dbg_conffdetail,
+                "process_archive conffile `%s' in package %s - conff ? not 
`%s'",
+                newconff->namenode->name, otherpkg->name, searchconff->name);
+        if (searchconff) {
+          debug(dbg_conff,
+                "process_archive conffile `%s' package=%s %s hash=%s",
+                newconff->namenode->name, otherpkg->name,
+                otherpkg == pkg ? "same" : "different!",
+                searchconff->hash);
+          if (otherpkg == pkg)
+            break;
         }
       }
-    xit_conff_hashcopy_srch:
+      filepackages_iter_free(iter);
+
       if (searchconff) {
         newconff->namenode->oldhash= searchconff->hash;
        /* we don't copy `obsolete'; it's not obsolete in the new package */
@@ -1158,6 +1160,8 @@ void process_archive(const char *filename) {
    * have claimed `ownership' of all its files.
    */
   for (cfile= newfileslist; cfile; cfile= cfile->next) {
+    struct filepackages_iterator *iter;
+
     if (!(cfile->namenode->flags & fnnf_elide_other_lists)) continue;
     if (cfile->namenode->divert && cfile->namenode->divert->useinstead) {
       divpkg= cfile->namenode->divert->pkg;
@@ -1176,30 +1180,26 @@ void process_archive(const char *filename) {
       debug(dbg_eachfile, "process_archive looking for overwriting `%s'",
             cfile->namenode->name);
     }
-    for (packageslump= cfile->namenode->packages;
-         packageslump;
-         packageslump= packageslump->more) {
-      for (i=0; i < PERFILEPACKAGESLUMP && packageslump->pkgs[i]; i++) {
-        otherpkg= packageslump->pkgs[i];
-        debug(dbg_eachfiledetail, "process_archive ... found in 
%s\n",otherpkg->name);
-        /* If !fileslistvalid then it's one of the disappeared packages above
-         * and we don't bother with it here, clearly.
-         */
-        if (otherpkg == pkg || !otherpkg->clientdata->fileslistvalid) continue;
-        if (otherpkg == divpkg) {
-          debug(dbg_eachfiledetail, "process_archive ... diverted, 
skipping\n");
-          continue;
-        }
-
-        /* Found one.  We delete remove the list entry for this file,
-         * (and any others in the same package) and then mark the package
-         * as requiring a reread.
-         */
-        write_filelist_except(otherpkg, otherpkg->clientdata->files, 1);
-        ensure_package_clientdata(otherpkg);
-        debug(dbg_veryverbose, "process_archive overwrote from 
%s",otherpkg->name);
+    iter = filepackages_iter_new(cfile->namenode);
+    while ((otherpkg = filepackages_iter_next(iter))) {
+      debug(dbg_eachfiledetail, "process_archive ... found in %s\n", 
otherpkg->name);
+      /* If !fileslistvalid then it's one of the disappeared packages above
+       * and we don't bother with it here, clearly. */
+      if (otherpkg == pkg || !otherpkg->clientdata->fileslistvalid)
+        continue;
+      if (otherpkg == divpkg) {
+        debug(dbg_eachfiledetail, "process_archive ... diverted, skipping\n");
+        continue;
       }
+
+      /* Found one. We delete remove the list entry for this file,
+       * (and any others in the same package) and then mark the package
+       * as requiring a reread. */
+      write_filelist_except(otherpkg, otherpkg->clientdata->files, 1);
+      ensure_package_clientdata(otherpkg);
+      debug(dbg_veryverbose, "process_archive overwrote from %s", 
otherpkg->name);
     }
+    filepackages_iter_free(iter);
   }
 
   /* Right, the package we've unpacked is now in a reasonable state.
diff --git a/src/query.c b/src/query.c
index 7e9ea4d..7f8d769 100644
--- a/src/query.c
+++ b/src/query.c
@@ -192,8 +192,9 @@ listpackages(const char *const *argv)
 }
 
 static int searchoutput(struct filenamenode *namenode) {
-  int found, i;
-  struct filepackages *packageslump;
+  struct filepackages_iterator *iter;
+  struct pkginfo *pkg_owner;
+  int found;
 
   if (namenode->divert) {
     const char *name_from = namenode->divert->camefrom ?
@@ -212,15 +213,16 @@ static int searchoutput(struct filenamenode *namenode) {
     }
   }
   found= 0;
-  for (packageslump= namenode->packages;
-       packageslump;
-       packageslump= packageslump->more) {
-    for (i=0; i < PERFILEPACKAGESLUMP && packageslump->pkgs[i]; i++) {
-      if (found) fputs(", ",stdout);
-      fputs(packageslump->pkgs[i]->name,stdout);
-      found++;
-    }
+
+  iter = filepackages_iter_new(namenode);
+  while ((pkg_owner = filepackages_iter_next(iter))) {
+    if (found)
+      fputs(", ", stdout);
+    fputs(pkg_owner->name, stdout);
+    found++;
   }
+  filepackages_iter_free(iter);
+
   if (found) printf(": %s\n",namenode->name);
   return found + (namenode->divert ? 1 : 0);
 }

-- 
dpkg's main repository


-- 
To UNSUBSCRIBE, email to debian-dpkg-cvs-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org

Reply via email to