Browse Source

libdpkg: Centralize compressor knowledge into the compress module

Create a new structure to hold the name, extension, and compress and
decompress methods for each compressor. Add new functions to find
the correct compressor by name and extension. This way we have the
information localized in a single place.
Guillem Jover 16 years ago
parent
commit
95b61194f3
6 changed files with 110 additions and 85 deletions
  1. 6 19
      dpkg-deb/build.c
  2. 1 4
      dpkg-deb/dpkg-deb.h
  3. 10 17
      dpkg-deb/extract.c
  4. 3 10
      dpkg-deb/main.c
  5. 75 28
      lib/dpkg/compress.c
  6. 15 7
      lib/dpkg/compress.h

+ 6 - 19
dpkg-deb/build.c

@@ -432,7 +432,7 @@ void do_build(const char *const *argv) {
   c2 = subproc_fork();
   if (!c2) {
     m_dup2(p1[0],0); m_dup2(gzfd,1); close(p1[0]); close(gzfd);
-    compress_filter(compress_type_gzip, 0, 1, 9, _("control"));
+    compress_filter(&compressor_gzip, 0, 1, 9, _("control"));
   }
   close(p1[0]);
   subproc_wait_check(c2, "gzip -9c", 0);
@@ -498,7 +498,7 @@ void do_build(const char *const *argv) {
     close(p1[1]);
     m_dup2(p2[0],0); close(p2[0]);
     m_dup2(oldformatflag ? fileno(ar) : gzfd,1);
-    compress_filter(compress_type, 0, 1, compress_level, _("data"));
+    compress_filter(compressor, 0, 1, compress_level, _("data"));
   }
   close(p2[0]);
   /* All the pipes are set, now lets run find, and start feeding
@@ -538,23 +538,10 @@ void do_build(const char *const *argv) {
   subproc_wait_check(c1, "tar -cf", 0);
   /* Okay, we have data.tar.gz as well now, add it to the ar wrapper */
   if (!oldformatflag) {
-    const char *datamember;
-    switch (compress_type) {
-    case compress_type_gzip:
-      datamember = DATAMEMBER_GZ;
-      break;
-    case compress_type_bzip2:
-      datamember = DATAMEMBER_BZ2;
-      break;
-    case compress_type_lzma:
-      datamember = DATAMEMBER_LZMA;
-      break;
-    case compress_type_none:
-      datamember = DATAMEMBER;
-      break;
-    default:
-      internerr("unknown compress_type '%i'", compress_type);
-    }
+    char datamember[16 + 1];
+
+    sprintf(datamember, "%s%s", DATAMEMBER, compressor->extension);
+
     if (fstat(gzfd, &datastab))
       ohshite(_("failed to fstat tmpfile (data)"));
     if (fprintf(ar,

+ 1 - 4
dpkg-deb/dpkg-deb.h

@@ -34,7 +34,7 @@ void extracthalf(const char *debar, const char *directory,
                  const char *taroption, int admininfo);
 
 extern const char* showformat;
-extern enum compress_type compress_type;
+extern struct compressor *compressor;
 extern int compress_level;
 
 #define ARCHIVEVERSION		"2.0"
@@ -54,9 +54,6 @@ extern int compress_level;
 
 #define DEBMAGIC		"debian-binary"
 #define ADMINMEMBER		"control.tar.gz"
-#define DATAMEMBER_GZ		"data.tar.gz"
-#define DATAMEMBER_BZ2		"data.tar.bz2"
-#define DATAMEMBER_LZMA		"data.tar.lzma"
 #define DATAMEMBER		"data.tar"
 
 #define MAXFILENAME 2048

+ 10 - 17
dpkg-deb/extract.c

@@ -124,7 +124,7 @@ void extracthalf(const char *debar, const char *directory,
   char *cur;
   struct ar_hdr arh;
   int readfromfd, oldformat= 0, header_done, adminmember;
-  enum compress_type compress_type = compress_type_gzip;
+  struct compressor *compressor = &compressor_gzip;
   
   ar= fopen(debar,"r"); if (!ar) ohshite(_("failed to read archive `%.255s'"),debar);
   if (fstat(fileno(ar),&stab)) ohshite(_("failed to fstat archive"));
@@ -172,26 +172,19 @@ void extracthalf(const char *debar, const char *directory,
       } else {
 	if (strncmp(arh.ar_name, ADMINMEMBER, sizeof(arh.ar_name)) == 0)
 	  adminmember = 1;
-	else
+	else {
 	  adminmember = -1;
 
-	if (adminmember == -1) {
-	  if (strncmp(arh.ar_name, DATAMEMBER_GZ, sizeof(arh.ar_name)) == 0) {
-	    adminmember= 0;
-	    compress_type = compress_type_gzip;
-	  } else if (strncmp(arh.ar_name, DATAMEMBER_BZ2, sizeof(arh.ar_name)) == 0) {
-	    adminmember= 0;
-	    compress_type = compress_type_bzip2;
-	  } else if (strncmp(arh.ar_name, DATAMEMBER_LZMA, sizeof(arh.ar_name)) == 0) {
-	    adminmember = 0;
-	    compress_type = compress_type_lzma;
-	  } else if (strncmp(arh.ar_name, DATAMEMBER, sizeof(arh.ar_name)) == 0) {
+	  if (strncmp(arh.ar_name, DATAMEMBER, strlen(DATAMEMBER)) == 0) {
+	    const char *extension = arh.ar_name + strlen(DATAMEMBER);
+
 	    adminmember= 0;
-	    compress_type = compress_type_none;
-	  } else {
+	    compressor = compressor_find_by_extension(extension);
+	  }
+
+          if (adminmember == -1 || compressor == NULL)
             ohshit(_("file `%.250s' contains ununderstood data member %.*s, giving up"),
                    debar, (int)sizeof(arh.ar_name), arh.ar_name);
-	  }
         }
         if (adminmember == 1) {
           if (ctrllennum != 0)
@@ -294,7 +287,7 @@ void extracthalf(const char *debar, const char *directory,
     m_dup2(readfromfd,0);
     if (admininfo) close(p1[0]);
     if (taroption) { m_dup2(p2[1],1); close(p2[0]); close(p2[1]); }
-    decompress_filter(compress_type, 0, 1, _("data"));
+    decompress_filter(compressor, 0, 1, _("data"));
   }
   if (readfromfd != fileno(ar)) close(readfromfd);
   if (taroption) close(p2[1]);

+ 3 - 10
dpkg-deb/main.c

@@ -134,7 +134,7 @@ const char printforhelp[]=
      "Type dpkg --help for help about installing and deinstalling packages.");
 
 int debugflag=0, nocheckflag=0, oldformatflag=BUILDOLDPKGFORMAT;
-enum compress_type compress_type = compress_type_gzip;
+struct compressor *compressor = &compressor_gzip;
 int compress_level = -1;
 const struct cmdinfo *cipaction = NULL;
 dofunction *action = NULL;
@@ -209,15 +209,8 @@ static void setaction(const struct cmdinfo *cip, const char *value) {
 }
 
 static void setcompresstype(const struct cmdinfo *cip, const char *value) {
-  if (!strcmp(value, "gzip"))
-    compress_type = compress_type_gzip;
-  else if (!strcmp(value, "bzip2"))
-    compress_type = compress_type_bzip2;
-  else if (!strcmp(value, "lzma"))
-    compress_type = compress_type_lzma;
-  else if (!strcmp(value, "none"))
-    compress_type = compress_type_none;
-  else
+  compressor = compressor_find_by_name(value);
+  if (compressor == NULL)
     ohshit(_("unknown compression type `%s'!"), value);
 }
 

+ 75 - 28
lib/dpkg/compress.c

@@ -87,6 +87,13 @@ compress_none(int fd_in, int fd_out, int compress_level, const char *desc)
 	exit(0);
 }
 
+struct compressor compressor_none = {
+	.name = "none",
+	.extension = "",
+	.compress = compress_none,
+	.decompress = decompress_none,
+};
+
 /*
  * Gzip compressor.
  */
@@ -191,6 +198,13 @@ compress_gzip(int fd_in, int fd_out, int compress_level, const char *desc)
 }
 #endif
 
+struct compressor compressor_gzip = {
+	.name = "gzip",
+	.extension = ".gz",
+	.compress = compress_gzip,
+	.decompress = decompress_gzip,
+};
+
 /*
  * Bzip2 compressor.
  */
@@ -300,6 +314,13 @@ compress_bzip2(int fd_in, int fd_out, int compress_level, const char *desc)
 }
 #endif
 
+struct compressor compressor_bzip2 = {
+	.name = "bzip2",
+	.extension = ".bz2",
+	.compress = compress_bzip2,
+	.decompress = decompress_bzip2,
+};
+
 /*
  * Lzma compressor.
  */
@@ -319,42 +340,77 @@ compress_lzma(int fd_in, int fd_out, int compress_level, const char *desc)
 	fd_fd_filter(fd_in, fd_out, desc, LZMA, combuf, NULL);
 }
 
+struct compressor compressor_lzma = {
+	.name = "lzma",
+	.extension = ".lzma",
+	.compress = compress_lzma,
+	.decompress = decompress_lzma,
+};
+
 /*
  * Generic compressor filter.
  */
 
+static struct compressor *compressor[] = {
+	&compressor_none,
+	&compressor_gzip,
+	&compressor_bzip2,
+	&compressor_lzma,
+};
+
+struct compressor *
+compressor_find_by_name(const char *name)
+{
+	size_t i;
+
+	for (i = 0; i < array_count(compressor); i++)
+		if (strcmp(compressor[i]->name, name) == 0)
+			return compressor[i];
+
+	return NULL;
+}
+
+struct compressor *
+compressor_find_by_extension(const char *extension)
+{
+	size_t i;
+
+	for (i = 0; i < array_count(compressor); i++)
+		if (strcmp(compressor[i]->extension, extension) == 0)
+			return compressor[i];
+
+	return NULL;
+}
+
 void
-decompress_filter(enum compress_type type, int fd_in, int fd_out,
+decompress_filter(struct compressor *compressor, int fd_in, int fd_out,
                   const char *desc_fmt, ...)
 {
 	va_list al;
 	struct varbuf desc = VARBUF_INIT;
 
+	if (compressor == NULL)
+		internerr("no compressor specified");
+
 	va_start(al, desc_fmt);
 	varbufvprintf(&desc, desc_fmt, al);
 	va_end(al);
 
-	switch (type) {
-	case compress_type_gzip:
-		decompress_gzip(fd_in, fd_out, desc.buf);
-	case compress_type_bzip2:
-		decompress_bzip2(fd_in, fd_out, desc.buf);
-	case compress_type_lzma:
-		decompress_lzma(fd_in, fd_out, desc.buf);
-	case compress_type_none:
-		decompress_none(fd_in, fd_out, desc.buf);
-	default:
-		exit(1);
-	}
+	compressor->decompress(fd_in, fd_out, desc.buf);
+
+	exit(0);
 }
 
 void
-compress_filter(enum compress_type type, int fd_in, int fd_out,
+compress_filter(struct compressor *compressor, int fd_in, int fd_out,
                 int compress_level, const char *desc_fmt, ...)
 {
 	va_list al;
 	struct varbuf desc = VARBUF_INIT;
 
+	if (compressor == NULL)
+		internerr("no compressor specified");
+
 	va_start(al, desc_fmt);
 	varbufvprintf(&desc, desc_fmt, al);
 	va_end(al);
@@ -362,18 +418,9 @@ compress_filter(enum compress_type type, int fd_in, int fd_out,
 	if (compress_level < 0)
 		compress_level = 9;
 	else if (compress_level == 0)
-		type = compress_type_none;
-
-	switch (type) {
-	case compress_type_gzip:
-		compress_gzip(fd_in, fd_out, compress_level, desc.buf);
-	case compress_type_bzip2:
-		compress_bzip2(fd_in, fd_out, compress_level, desc.buf);
-	case compress_type_lzma:
-		compress_lzma(fd_in, fd_out, compress_level, desc.buf);
-	case compress_type_none:
-		compress_none(fd_in, fd_out, compress_level, desc.buf);
-	default:
-		exit(1);
-	}
+		compressor = &compressor_none;
+
+	compressor->compress(fd_in, fd_out, compress_level, desc.buf);
+
+	exit(0);
 }

+ 15 - 7
lib/dpkg/compress.h

@@ -30,17 +30,25 @@ DPKG_BEGIN_DECLS
 #define BZIP2		"bzip2"
 #define LZMA		"lzma"
 
-enum compress_type {
-  compress_type_none,
-  compress_type_gzip,
-  compress_type_bzip2,
-  compress_type_lzma,
+struct compressor {
+	const char *name;
+	const char *extension;
+	void (*compress)(int fd_in, int fd_out, int level, const char *desc);
+	void (*decompress)(int fd_in, int fd_out, const char *desc);
 };
 
-void decompress_filter(enum compress_type type, int fd_in, int fd_out,
+struct compressor compressor_none;
+struct compressor compressor_gzip;
+struct compressor compressor_bzip2;
+struct compressor compressor_lzma;
+
+struct compressor *compressor_find_by_name(const char *name);
+struct compressor *compressor_find_by_extension(const char *name);
+
+void decompress_filter(struct compressor *comp, int fd_in, int fd_out,
                        const char *desc, ...) DPKG_ATTR_NORET
                        DPKG_ATTR_PRINTF(4);
-void compress_filter(enum compress_type type, int fd_in, int fd_out,
+void compress_filter(struct compressor *comp, int fd_in, int fd_out,
                      int compress_level, const char *desc, ...)
                      DPKG_ATTR_NORET DPKG_ATTR_PRINTF(5);