Explorar el Código

dpkg: Refactor infodb directory traversal into new pkg_infodb_foreach()

Move the common code into a new function which will call an action
pointer function on matched files to perform the specific logic.
Guillem Jover hace 15 años
padre
commit
a2acd17d3c
Se han modificado 6 ficheros con 69 adiciones y 134 borrados
  1. 1 0
      src/Makefile.am
  2. 56 0
      src/infodb.c
  3. 4 0
      src/infodb.h
  4. 5 56
      src/processarc.c
  5. 2 50
      src/querycmd.c
  6. 1 28
      src/remove.c

+ 1 - 0
src/Makefile.am

@@ -57,6 +57,7 @@ dpkg_divert_SOURCES = \
 
 dpkg_query_SOURCES = \
 	filesdb.c filesdb.h \
+	infodb.c infodb.h \
 	divertdb.c \
 	querycmd.c
 

+ 56 - 0
src/infodb.c

@@ -26,11 +26,13 @@
 #include <sys/stat.h>
 
 #include <errno.h>
+#include <dirent.h>
 #include <unistd.h>
 
 #include <dpkg/i18n.h>
 #include <dpkg/dpkg.h>
 #include <dpkg/dpkg-db.h>
+#include <dpkg/debug.h>
 
 #include "infodb.h"
 
@@ -48,3 +50,57 @@ pkg_infodb_has_file(struct pkginfo *pkg, const char *name)
 	else
 		ohshite(_("unable to check existence of `%.250s'"), filename);
 }
+
+void
+pkg_infodb_foreach(struct pkginfo *pkg, pkg_infodb_file_func *func)
+{
+	DIR *db_dir;
+	struct dirent *db_de;
+	struct varbuf db_path = VARBUF_INIT;
+	size_t db_path_len;
+
+	varbuf_add_str(&db_path, pkgadmindir());
+	db_path_len = db_path.used;
+	varbuf_add_char(&db_path, '\0');
+
+	db_dir = opendir(db_path.buf);
+	if (!db_dir)
+		ohshite(_("cannot read info directory"));
+
+	push_cleanup(cu_closedir, ~0, NULL, 0, 1, (void *)db_dir);
+	while ((db_de = readdir(db_dir)) != NULL) {
+		const char *filename, *filetype, *dot;
+
+		debug(dbg_veryverbose, "infodb foreach info file '%s'",
+		      db_de->d_name);
+
+		/* Ignore dotfiles, including ‘.’ and ‘..’. */
+		if (db_de->d_name[0] == '.')
+			continue;
+
+		/* Ignore anything odd. */
+		dot = strrchr(db_de->d_name, '.');
+		if (dot == NULL)
+			continue;
+
+		/* Ignore files from other packages. */
+		if (strlen(pkg->name) != (size_t)(dot - db_de->d_name) ||
+		    strncmp(db_de->d_name, pkg->name, dot - db_de->d_name))
+			continue;
+
+		debug(dbg_stupidlyverbose, "infodb foreach file this pkg");
+
+		/* Skip past the full stop. */
+		filetype = dot + 1;
+
+		varbuf_trunc(&db_path, db_path_len);
+		varbuf_add_str(&db_path, db_de->d_name);
+		varbuf_end_str(&db_path);
+		filename = db_path.buf;
+
+		func(filename, filetype);
+	}
+	pop_cleanup(ehflag_normaltidy); /* closedir */
+
+	varbuf_destroy(&db_path);
+}

+ 4 - 0
src/infodb.h

@@ -27,4 +27,8 @@
 
 bool pkg_infodb_has_file(struct pkginfo *pkg, const char *name);
 
+typedef void pkg_infodb_file_func(const char *filename, const char *filetype);
+
+void pkg_infodb_foreach(struct pkginfo *pkg, pkg_infodb_file_func *func);
+
 #endif /* DPKG_INFODB_H */

+ 5 - 56
src/processarc.c

@@ -50,6 +50,7 @@
 #include <dpkg/triglib.h>
 
 #include "filesdb.h"
+#include "infodb.h"
 #include "main.h"
 #include "archives.h"
 
@@ -240,10 +241,10 @@ void process_archive(const char *filename) {
   static char *cidir = NULL;
   static struct fileinlist *newconffiles, *newfileslist;
   static enum pkgstatus oldversionstatus;
-  static struct varbuf infofnvb, fnvb, depprobwhy;
+  static struct varbuf depprobwhy;
   static struct tarcontext tc;
 
-  int r, i, infodirlen, infodirbaseused;
+  int r, i;
   pid_t pid;
   struct pkgiterator *it;
   struct pkginfo *pkg, *otherpkg, *divpkg;
@@ -931,38 +932,8 @@ void process_archive(const char *filename) {
     match_head = match_node->next;
     match_node_free(match_node);
   }
-  varbuf_reset(&infofnvb);
-  varbuf_add_str(&infofnvb, pkgadmindir());
-  infodirlen= infofnvb.used;
-  varbuf_end_str(&infofnvb);
-  dsd= opendir(infofnvb.buf);
-  if (!dsd) ohshite(_("cannot read info directory"));
-  push_cleanup(cu_closedir, ~0, NULL, 0, 1, (void *)dsd);
-  while ((de = readdir(dsd)) != NULL) {
-    debug(dbg_veryverbose, "process_archive info file `%s'", de->d_name);
-    /* Ignore dotfiles, including ‘.’ and ‘..’. */
-    if (de->d_name[0] == '.')
-      continue;
-    /* Ignore anything odd. */
-    p = strrchr(de->d_name, '.');
-    if (!p)
-      continue;
-    if (strlen(pkg->name) != (size_t)(p-de->d_name) ||
-        strncmp(de->d_name,pkg->name,p-de->d_name)) continue;
-
-    debug(dbg_stupidlyverbose, "process_archive info this pkg");
-    /* Right, do we have one? */
-
-    /* Skip past the full stop. */
-    p++;
-
-    varbuf_trunc(&infofnvb, infodirlen);
-    varbuf_add_str(&infofnvb, de->d_name);
-    varbuf_end_str(&infofnvb);
 
-    pkg_infodb_update_file(infofnvb.buf, p);
-  }
-  pop_cleanup(ehflag_normaltidy); /* closedir */
+  pkg_infodb_foreach(pkg, pkg_infodb_update_file);
 
   while ((match_node = match_head)) {
     strcpy(cidirrest, match_node->filetype);
@@ -1195,30 +1166,8 @@ void process_archive(const char *filename) {
                                 NULL);
 
     /* OK, now we delete all the stuff in the ‘info’ directory .. */
-    varbuf_reset(&fnvb);
-    varbuf_add_str(&fnvb, pkgadmindir());
-    infodirbaseused= fnvb.used;
-    varbuf_end_str(&fnvb);
-    dsd= opendir(fnvb.buf); if (!dsd) ohshite(_("cannot read info directory"));
-    push_cleanup(cu_closedir, ~0, NULL, 0, 1, (void *)dsd);
-
     debug(dbg_general, "process_archive disappear cleaning info directory");
-
-    while ((de = readdir(dsd)) != NULL) {
-      debug(dbg_veryverbose, "process_archive info file `%s'", de->d_name);
-      if (de->d_name[0] == '.') continue;
-      p= strrchr(de->d_name,'.'); if (!p) continue;
-      if (strlen(otherpkg->name) != (size_t)(p-de->d_name) ||
-          strncmp(de->d_name,otherpkg->name,p-de->d_name)) continue;
-      debug(dbg_stupidlyverbose, "process_archive info this pkg");
-      varbuf_trunc(&fnvb, infodirbaseused);
-      varbuf_add_str(&fnvb, de->d_name);
-      varbuf_end_str(&fnvb);
-
-      pkg_infodb_remove_file(fnvb.buf, p + 1);
-    }
-    pop_cleanup(ehflag_normaltidy); /* closedir */
-
+    pkg_infodb_foreach(otherpkg, pkg_infodb_remove_file);
     dir_sync_path(pkgadmindir());
 
     otherpkg->status= stat_notinstalled;

+ 2 - 50
src/querycmd.c

@@ -49,6 +49,7 @@
 #include <dpkg/myopt.h>
 
 #include "filesdb.h"
+#include "infodb.h"
 #include "main.h"
 
 static const char* showformat		= "${Package}\t${Version}\n";
@@ -543,55 +544,6 @@ control_path_file(struct pkginfo *pkg, const char *control_file)
   pkg_infodb_print_filename(control_path, control_file);
 }
 
-static void
-control_path_pkg(struct pkginfo *pkg)
-{
-  DIR *db_dir;
-  struct dirent *db_de;
-  struct varbuf db_path;
-  size_t db_path_len;
-
-  varbuf_init(&db_path, 0);
-  varbuf_add_str(&db_path, pkgadmindir());
-  db_path_len = db_path.used;
-  varbuf_end_str(&db_path);
-
-  db_dir = opendir(db_path.buf);
-  if (!db_dir)
-    ohshite(_("cannot read info directory"));
-
-  push_cleanup(cu_closedir, ~0, NULL, 0, 1, (void *)db_dir);
-  while ((db_de = readdir(db_dir)) != NULL) {
-    const char *p;
-
-    /* Ignore dotfiles, including ‘.’ and ‘..’. */
-    if (db_de->d_name[0] == '.')
-      continue;
-
-    /* Ignore anything odd. */
-    p = strrchr(db_de->d_name, '.');
-    if (!p)
-      continue;
-
-    /* Ignore files from other packages. */
-    if (strlen(pkg->name) != (size_t)(p - db_de->d_name) ||
-        strncmp(db_de->d_name, pkg->name, p - db_de->d_name))
-      continue;
-
-    /* Skip past the full stop. */
-    p++;
-
-    varbuf_trunc(&db_path, db_path_len);
-    varbuf_add_str(&db_path, db_de->d_name);
-    varbuf_end_str(&db_path);
-
-    pkg_infodb_print_filename(db_path.buf, p);
-  }
-  pop_cleanup(ehflag_normaltidy); /* closedir */
-
-  varbuf_destroy(&db_path);
-}
-
 static int
 control_path(const char *const *argv)
 {
@@ -626,7 +578,7 @@ control_path(const char *const *argv)
   if (control_file)
     control_path_file(pkg, control_file);
   else
-    control_path_pkg(pkg);
+    pkg_infodb_foreach(pkg, pkg_infodb_print_filename);
 
   modstatdb_shutdown();
 

+ 1 - 28
src/remove.c

@@ -204,13 +204,10 @@ static void
 removal_bulk_remove_files(struct pkginfo *pkg)
 {
   int before;
-  int infodirbaseused;
   struct reversefilelistiter rlistit;
   struct fileinlist *leftover;
   struct filenamenode *namenode;
   static struct varbuf fnvb;
-  DIR *dsd;
-  struct dirent *de;
   struct stat stab;
 
     pkg->status= stat_halfinstalled;
@@ -289,33 +286,9 @@ removal_bulk_remove_files(struct pkginfo *pkg)
     write_filelist_except(pkg,leftover,0);
     maintainer_script_installed(pkg, POSTRMFILE, "post-removal",
                                 "remove", NULL);
-    varbuf_reset(&fnvb);
-    varbuf_add_str(&fnvb, pkgadmindir());
-    infodirbaseused= fnvb.used;
-    varbuf_end_str(&fnvb);
-    dsd= opendir(fnvb.buf); if (!dsd) ohshite(_("cannot read info directory"));
-    push_cleanup(cu_closedir, ~0, NULL, 0, 1, (void *)dsd);
 
     debug(dbg_general, "removal_bulk cleaning info directory");
-
-    while ((de = readdir(dsd)) != NULL) {
-    char *p;
-
-      debug(dbg_veryverbose, "removal_bulk info file `%s'", de->d_name);
-      if (de->d_name[0] == '.') continue;
-      p= strrchr(de->d_name,'.'); if (!p) continue;
-      if (strlen(pkg->name) != (size_t)(p-de->d_name) ||
-          strncmp(de->d_name,pkg->name,p-de->d_name)) continue;
-      debug(dbg_stupidlyverbose, "removal_bulk info this pkg");
-
-      varbuf_trunc(&fnvb, infodirbaseused);
-      varbuf_add_str(&fnvb, de->d_name);
-      varbuf_end_str(&fnvb);
-
-      removal_bulk_remove_file(fnvb.buf, p + 1);
-    }
-    pop_cleanup(ehflag_normaltidy); /* closedir */
-
+    pkg_infodb_foreach(pkg, removal_bulk_remove_file);
     dir_sync_path(pkgadmindir());
 
     pkg->status= stat_configfiles;