Browse Source

libdpkg: Switch buffer I/O code to use struct dpkg_error

As a side effect this mkes the messages more clear as the caller has
more context to describe the error conditions.

Closes: #621763
Guillem Jover 15 years ago
parent
commit
bd0da280d1

+ 1 - 0
debian/changelog

@@ -36,6 +36,7 @@ dpkg (1.16.5) UNRELEASED; urgency=low
     replace the now deprecated --control-path.
   * Print master and slave alternarive link names in update-alternatives
     --query and always print alternative link in --config. Closes: #679010
+  * Cleanup and clarify buffer I/O error reporting. Closes: #621763
 
   [ Updated dpkg translations ]
   * Swedish (Peter Krefting).

+ 6 - 3
dpkg-deb/build.c

@@ -387,6 +387,7 @@ pkg_get_pathname(const char *dir, struct pkginfo *pkg)
 int
 do_build(const char *const *argv)
 {
+  struct dpkg_error err;
   const char *debar, *dir;
   bool subdir;
   char *tfbuf;
@@ -482,7 +483,7 @@ do_build(const char *const *argv)
     params.strategy = compressor_strategy_none;
     params.level = 9;
 
-    compress_filter(&params, p1[0], gzfd, _("control member"));
+    compress_filter(&params, p1[0], gzfd, _("compressing control member"));
     exit(0);
   }
   close(p1[0]);
@@ -504,7 +505,9 @@ do_build(const char *const *argv)
             (intmax_t)controlstab.st_size);
     if (fd_write(arfd, versionbuf, strlen(versionbuf)) < 0)
       ohshite(_("error writing `%s'"), debar);
-    fd_fd_copy(gzfd, arfd, -1, _("control member"));
+    if (fd_fd_copy(gzfd, arfd, -1, &err) < 0)
+      ohshit(_("cannot copy '%s' into archive '%s': %s"), _("control member"),
+             debar, err.str);
   } else {
     const char deb_magic[] = ARCHIVEVERSION "\n";
 
@@ -551,7 +554,7 @@ do_build(const char *const *argv)
   c2 = subproc_fork();
   if (!c2) {
     close(p1[1]);
-    compress_filter(&compress_params, p2[0], gzfd, _("data member"));
+    compress_filter(&compress_params, p2[0], gzfd, _("compressing data member"));
     exit(0);
   }
   close(p2[0]);

+ 14 - 9
dpkg-deb/extract.c

@@ -107,6 +107,7 @@ void
 extracthalf(const char *debar, const char *dir, const char *taroption,
             int admininfo)
 {
+  struct dpkg_error err;
   const char *errstr;
   char versionbuf[40];
   struct deb_version version;
@@ -174,8 +175,8 @@ extracthalf(const char *debar, const char *dir, const char *taroption,
       } else if (arh.ar_name[0] == '_') {
         /* Members with ‘_’ are noncritical, and if we don't understand
          * them we skip them. */
-        fd_skip(arfd, memberlen + (memberlen & 1),
-                _("skipped archive member data from %s"), debar);
+        if (fd_skip(arfd, memberlen + (memberlen & 1), &err) < 0)
+          ohshit(_("cannot skip archive member from '%s': %s"), debar, err.str);
       } else {
 	if (strncmp(arh.ar_name, ADMINMEMBER, sizeof(arh.ar_name)) == 0)
 	  adminmember = 1;
@@ -200,8 +201,8 @@ extracthalf(const char *debar, const char *dir, const char *taroption,
           ctrllennum= memberlen;
         }
         if (!adminmember != !admininfo) {
-          fd_skip(arfd, memberlen + (memberlen & 1),
-                  _("skipped archive member data from %s"), debar);
+          if (fd_skip(arfd, memberlen + (memberlen & 1), &err) < 0)
+            ohshit(_("cannot skip archive member from '%s': %s"), debar, err.str);
         } else {
           /* Yes! - found it. */
           break;
@@ -239,8 +240,9 @@ extracthalf(const char *debar, const char *dir, const char *taroption,
       memberlen = ctrllennum;
     } else {
       memberlen = stab.st_size - ctrllennum - strlen(ctrllenbuf) - l;
-      fd_skip(arfd, ctrllennum,
-              _("skipped archive control member data from %s"), debar);
+      if (fd_skip(arfd, ctrllennum, &err) < 0)
+        ohshit(_("cannot skip archive control member from '%s': %s"), debar,
+               err.str);
     }
 
     if (admininfo >= 2) {
@@ -265,9 +267,11 @@ extracthalf(const char *debar, const char *dir, const char *taroption,
   c1 = subproc_fork();
   if (!c1) {
     close(p1[0]);
-    fd_fd_copy(arfd, p1[1], memberlen, _("failed to write to pipe in copy"));
+    if (fd_fd_copy(arfd, p1[1], memberlen, &err) < 0)
+      ohshit(_("cannot copy archive member from '%s' to decompressor pipe: %s"),
+             debar, err.str);
     if (close(p1[1]))
-      ohshite(_("failed to close pipe in copy"));
+      ohshite(_("cannot close decompressor pipe"));
     exit(0);
   }
   close(p1[1]);
@@ -283,7 +287,8 @@ extracthalf(const char *debar, const char *dir, const char *taroption,
   if (!c2) {
     if (taroption)
       close(p2[0]);
-    decompress_filter(decompressor, p1[0], p2_out, _("data"));
+    decompress_filter(decompressor, p1[0], p2_out,
+                      _("decompressing archive member"));
     exit(0);
   }
   close(p1[0]);

+ 4 - 1
dpkg-deb/info.c

@@ -92,6 +92,7 @@ static int ilist_select(const struct dirent *de) {
 static void
 info_spew(const char *debar, const char *dir, const char *const *argv)
 {
+  struct dpkg_error err;
   const char *component;
   struct varbuf controlfile = VARBUF_INIT;
   int fd;
@@ -103,7 +104,9 @@ info_spew(const char *debar, const char *dir, const char *const *argv)
 
     fd = open(controlfile.buf, O_RDONLY);
     if (fd >= 0) {
-      fd_fd_copy(fd, 1, -1, _("control file '%s'"), controlfile.buf);
+      if (fd_fd_copy(fd, 1, -1, &err) < 0)
+        ohshit(_("cannot extract control file '%s' from '%s': %s"),
+               controlfile.buf, debar, err.str);
       close(fd);
     } else if (errno == ENOENT) {
       fprintf(stderr,

+ 7 - 2
dpkg-split/join.c

@@ -38,6 +38,7 @@
 #include "dpkg-split.h"
 
 void reassemble(struct partinfo **partlist, const char *outputfile) {
+  struct dpkg_error err;
   int fd_out, fd_in;
   unsigned int i;
 
@@ -55,8 +56,12 @@ void reassemble(struct partinfo **partlist, const char *outputfile) {
     fd_in = open(pi->filename, O_RDONLY);
     if (fd_in < 0)
       ohshite(_("unable to (re)open input part file `%.250s'"), pi->filename);
-    fd_skip(fd_in, pi->headerlen, _("skipping split package header"));
-    fd_fd_copy(fd_in, fd_out, pi->thispartlen, _("split package part"));
+    if (fd_skip(fd_in, pi->headerlen, &err) < 0)
+      ohshit(_("cannot skip split package header for '%s': %s"), pi->filename,
+             err.str);
+    if (fd_fd_copy(fd_in, fd_out, pi->thispartlen, &err) < 0)
+      ohshit(_("cannot append split package part '%s' to '%s': %s"),
+             pi->filename, outputfile, err.str);
     close(fd_in);
 
     printf("%d ",i+1);

+ 4 - 1
dpkg-split/queue.c

@@ -172,6 +172,7 @@ do_auto(const char *const *argv)
   for (j=refi->maxpartn-1; j>=0 && partlist[j]; j--);
 
   if (j>=0) {
+    struct dpkg_error err;
     int fd_src, fd_dst;
     int ap;
     char *p, *q;
@@ -187,7 +188,9 @@ do_auto(const char *const *argv)
     if (fd_dst < 0)
       ohshite(_("unable to open new depot file `%.250s'"), p);
 
-    fd_fd_copy(fd_src, fd_dst, refi->filesize, _("extracting split part"));
+    if (fd_fd_copy(fd_src, fd_dst, refi->filesize, &err) < 0)
+      ohshit(_("cannot extract split package part '%s': %s"),
+             partfile, err.str);
 
     if (fsync(fd_dst))
       ohshite(_("unable to sync file '%s'"), p);

+ 8 - 2
dpkg-split/split.c

@@ -51,6 +51,7 @@
 static char *
 deb_field(const char *filename, const char *field)
 {
+	struct dpkg_error err;
 	pid_t pid;
 	int p[2];
 	struct varbuf buf = VARBUF_INIT;
@@ -73,7 +74,9 @@ deb_field(const char *filename, const char *field)
 
 	/* Parant reads from pipe. */
 	varbuf_reset(&buf);
-	fd_vbuf_copy(p[0], &buf, -1, _("package field value extraction"));
+	if (fd_vbuf_copy(p[0], &buf, -1, &err) < 0)
+		ohshit(_("cannot extract package field value from '%s': %s"),
+		       filename, err.str);
 	varbuf_end_str(&buf);
 
 	close(p[0]);
@@ -114,6 +117,7 @@ static int
 mksplit(const char *file_src, const char *prefix, off_t maxpartsize,
         bool msdos)
 {
+	struct dpkg_error err;
 	int fd_src;
 	struct stat st;
 	char hash[MD5HASHLEN + 1];
@@ -134,7 +138,9 @@ mksplit(const char *file_src, const char *prefix, off_t maxpartsize,
 	if (!S_ISREG(st.st_mode))
 		ohshit(_("source file `%.250s' not a plain file"), file_src);
 
-	fd_md5(fd_src, hash, -1, "md5hash");
+	if (fd_md5(fd_src, hash, -1, &err) < 0)
+		ohshit(_("cannot compute MD5 hash for file '%s': %s"),
+		       file_src, err.str);
 	lseek(fd_src, 0, SEEK_SET);
 
 	/* FIXME: Use libdpkg-deb. */

+ 5 - 1
lib/dpkg/ar.c

@@ -127,6 +127,8 @@ void
 dpkg_ar_member_put_file(const char *ar_name, int ar_fd,
                         const char *name, int fd, off_t size)
 {
+	struct dpkg_error err;
+
 	if (size <= 0) {
 		struct stat st;
 
@@ -138,7 +140,9 @@ dpkg_ar_member_put_file(const char *ar_name, int ar_fd,
 	dpkg_ar_member_put_header(ar_name, ar_fd, name, size);
 
 	/* Copy data contents. */
-	fd_fd_copy(fd, ar_fd, size, _("ar member file (%s)"), name);
+	if (fd_fd_copy(fd, ar_fd, size, &err) < 0)
+		ohshit(_("cannot append ar member file (%s) to '%s': %s"),
+		       name, ar_name, err.str);
 
 	if (size & 1)
 		if (fd_write(ar_fd, "\n", 1) < 0)

+ 23 - 50
lib/dpkg/buffer.c

@@ -118,7 +118,8 @@ buffer_filter_done(struct buffer_data *data)
 }
 
 static off_t
-buffer_write(struct buffer_data *data, const void *buf, off_t length)
+buffer_write(struct buffer_data *data, const void *buf, off_t length,
+             struct dpkg_error *err)
 {
 	off_t ret = length;
 
@@ -128,6 +129,8 @@ buffer_write(struct buffer_data *data, const void *buf, off_t length)
 		break;
 	case BUFFER_WRITE_FD:
 		ret = fd_write(data->arg.i, buf, length);
+		if (ret < 0)
+			dpkg_put_errno(err, _("failed to write"));
 		break;
 	case BUFFER_WRITE_NULL:
 		break;
@@ -139,13 +142,16 @@ buffer_write(struct buffer_data *data, const void *buf, off_t length)
 }
 
 static off_t
-buffer_read(struct buffer_data *data, void *buf, off_t length)
+buffer_read(struct buffer_data *data, void *buf, off_t length,
+            struct dpkg_error *err)
 {
 	off_t ret;
 
 	switch (data->type) {
 	case BUFFER_READ_FD:
 		ret = fd_read(data->arg.i, buf, length);
+		if (ret < 0)
+			dpkg_put_errno(err, _("failed to read"));
 		break;
 	default:
 		internerr("unknown data type %i", data->type);
@@ -171,7 +177,7 @@ static off_t
 buffer_copy(struct buffer_data *read_data,
             struct buffer_data *filter,
             struct buffer_data *write_data,
-            off_t limit, const char *desc)
+            off_t limit, struct dpkg_error *err)
 {
 	char *buf;
 	int bufsize = 32768;
@@ -188,9 +194,9 @@ buffer_copy(struct buffer_data *read_data,
 	buffer_filter_init(filter);
 
 	while (bufsize > 0) {
-		bytesread = buffer_read(read_data, buf, bufsize);
+		bytesread = buffer_read(read_data, buf, bufsize, err);
 		if (bytesread < 0)
-			ohshite(_("failed to read on buffer copy for %s"), desc);
+			return -1;
 		if (bytesread == 0)
 			break;
 
@@ -204,9 +210,9 @@ buffer_copy(struct buffer_data *read_data,
 
 		buffer_filter_update(filter, buf, bytesread);
 
-		byteswritten = buffer_write(write_data, buf, bytesread);
+		byteswritten = buffer_write(write_data, buf, bytesread, err);
 		if (byteswritten < 0)
-			ohshite(_("failed in write on buffer copy for %s"), desc);
+			return -1;
 		if (byteswritten == 0)
 			break;
 
@@ -214,7 +220,7 @@ buffer_copy(struct buffer_data *read_data,
 	}
 
 	if (limit > 0)
-		ohshit(_("short read on buffer copy for %s"), desc);
+		return dpkg_put_error(err, _("unexpected end of file or stream"));
 
 	buffer_filter_done(filter);
 
@@ -227,52 +233,30 @@ off_t
 buffer_copy_IntInt(int Iin, int Tin,
                    void *Pfilter, int Tfilter,
                    int Iout, int Tout,
-                   off_t limit, const char *desc, ...)
+                   off_t limit, struct dpkg_error *err)
 {
-	va_list args;
 	struct buffer_data read_data = { .type = Tin, .arg.i = Iin };
 	struct buffer_data filter = { .type = Tfilter, .arg.ptr = Pfilter };
 	struct buffer_data write_data = { .type = Tout, .arg.i = Iout };
-	struct varbuf v = VARBUF_INIT;
-	off_t ret;
-
-	va_start(args, desc);
-	varbuf_vprintf(&v, desc, args);
-	va_end(args);
-
-	ret = buffer_copy(&read_data, &filter, &write_data, limit, v.buf);
-
-	varbuf_destroy(&v);
 
-	return ret;
+	return buffer_copy(&read_data, &filter, &write_data, limit, err);
 }
 
 off_t
 buffer_copy_IntPtr(int Iin, int Tin,
                    void *Pfilter, int Tfilter,
                    void *Pout, int Tout,
-                   off_t limit, const char *desc, ...)
+                   off_t limit, struct dpkg_error *err)
 {
-	va_list args;
 	struct buffer_data read_data = { .type = Tin, .arg.i = Iin };
 	struct buffer_data filter = { .type = Tfilter, .arg.ptr = Pfilter };
 	struct buffer_data write_data = { .type = Tout, .arg.ptr = Pout };
-	struct varbuf v = VARBUF_INIT;
-	off_t ret;
-
-	va_start(args, desc);
-	varbuf_vprintf(&v, desc, args);
-	va_end(args);
-
-	ret = buffer_copy(&read_data, &filter, &write_data, limit, v.buf);
 
-	varbuf_destroy(&v);
-
-	return ret;
+	return buffer_copy(&read_data, &filter, &write_data, limit, err);
 }
 
 static off_t
-buffer_skip(struct buffer_data *input, off_t limit, const char *desc)
+buffer_skip(struct buffer_data *input, off_t limit, struct dpkg_error *err)
 {
 	struct buffer_data output;
 	struct buffer_data filter;
@@ -282,7 +266,7 @@ buffer_skip(struct buffer_data *input, off_t limit, const char *desc)
 		if (lseek(input->arg.i, limit, SEEK_CUR) != -1)
 			return limit;
 		if (errno != ESPIPE)
-			ohshite(_("failed to seek %s"), desc);
+			return dpkg_put_errno(err, _("failed to seek"));
 		break;
 	default:
 		internerr("unknown data type %i", input->type);
@@ -293,24 +277,13 @@ buffer_skip(struct buffer_data *input, off_t limit, const char *desc)
 	filter.type = BUFFER_FILTER_NULL;
 	filter.arg.ptr = NULL;
 
-	return buffer_copy(input, &filter, &output, limit, desc);
+	return buffer_copy(input, &filter, &output, limit, err);
 }
 
 off_t
-buffer_skip_Int(int I, int T, off_t limit, const char *desc_fmt, ...)
+buffer_skip_Int(int I, int T, off_t limit, struct dpkg_error *err)
 {
-	va_list args; \
 	struct buffer_data input = { .type = T, .arg.i = I };
-	struct varbuf v = VARBUF_INIT;
-	off_t ret;
-
-	va_start(args, desc_fmt);
-	varbuf_vprintf(&v, desc_fmt, args);
-	va_end(args);
 
-	ret = buffer_skip(&input, limit, v.buf);
-
-	varbuf_destroy(&v);
-
-	return ret;
+	return buffer_skip(&input, limit, err);
 }

+ 17 - 16
lib/dpkg/buffer.h

@@ -27,6 +27,7 @@
 #include <sys/types.h>
 
 #include <dpkg/macros.h>
+#include <dpkg/error.h>
 
 DPKG_BEGIN_DECLS
 
@@ -58,42 +59,42 @@ struct buffer_data {
 # define buffer_md5(buf, hash, limit) \
 	buffer_filter(buf, hash, BUFFER_FILTER_MD5, limit)
 
-# define fd_md5(fd, hash, limit, ...) \
+# define fd_md5(fd, hash, limit, err) \
 	buffer_copy_IntPtr(fd, BUFFER_READ_FD, \
 	                   hash, BUFFER_FILTER_MD5, \
 	                   NULL, BUFFER_WRITE_NULL, \
-	                   limit, __VA_ARGS__)
-# define fd_fd_copy(fd1, fd2, limit, ...) \
+	                   limit, err)
+# define fd_fd_copy(fd1, fd2, limit, err) \
 	buffer_copy_IntInt(fd1, BUFFER_READ_FD, \
 	                   NULL, BUFFER_FILTER_NULL, \
 	                   fd2, BUFFER_WRITE_FD, \
-	                   limit, __VA_ARGS__)
-# define fd_fd_copy_and_md5(fd1, fd2, hash, limit, ...) \
+	                   limit, err)
+# define fd_fd_copy_and_md5(fd1, fd2, hash, limit, err) \
 	buffer_copy_IntInt(fd1, BUFFER_READ_FD, \
 	                   hash, BUFFER_FILTER_MD5, \
 	                   fd2, BUFFER_WRITE_FD, \
-	                   limit, __VA_ARGS__)
-# define fd_vbuf_copy(fd, buf, limit, ...) \
+	                   limit, err)
+# define fd_vbuf_copy(fd, buf, limit, err) \
 	buffer_copy_IntPtr(fd, BUFFER_READ_FD, \
 	                   NULL, BUFFER_FILTER_NULL, \
 	                   buf, BUFFER_WRITE_VBUF, \
-	                   limit, __VA_ARGS__)
-# define fd_skip(fd, limit, ...) \
-	buffer_skip_Int(fd, BUFFER_READ_FD, limit, __VA_ARGS__)
+	                   limit, err)
+# define fd_skip(fd, limit, err) \
+	buffer_skip_Int(fd, BUFFER_READ_FD, limit, err)
 
 
 off_t buffer_copy_IntPtr(int i, int typeIn,
                          void *f, int typeFilter,
                          void *p, int typeOut,
-                         off_t limit, const char *desc,
-                         ...) DPKG_ATTR_PRINTF(8);
+                         off_t limit, struct dpkg_error *err)
+	DPKG_ATTR_REQRET;
 off_t buffer_copy_IntInt(int i1, int typeIn,
                          void *f, int typeFilter,
                          int i2, int typeOut,
-                         off_t limit, const char *desc,
-                         ...) DPKG_ATTR_PRINTF(8);
-off_t buffer_skip_Int(int I, int T, off_t limit, const char *desc_fmt, ...)
-	DPKG_ATTR_PRINTF(4);
+                         off_t limit, struct dpkg_error *err)
+	DPKG_ATTR_REQRET;
+off_t buffer_skip_Int(int I, int T, off_t limit, struct dpkg_error *err)
+	DPKG_ATTR_REQRET;
 off_t buffer_filter(const void *buf, void *hash, int typeFilter, off_t length);
 
 /** @} */

+ 8 - 2
lib/dpkg/compress.c

@@ -102,13 +102,19 @@ fixup_none_params(struct compress_params *params)
 static void
 decompress_none(int fd_in, int fd_out, const char *desc)
 {
-	fd_fd_copy(fd_in, fd_out, -1, _("%s: decompression"), desc);
+	struct dpkg_error err;
+
+	if (fd_fd_copy(fd_in, fd_out, -1, &err) < 0)
+		ohshit(_("%s: pass-through copy error: %s"), desc, err.str);
 }
 
 static void
 compress_none(int fd_in, int fd_out, struct compress_params *params, const char *desc)
 {
-	fd_fd_copy(fd_in, fd_out, -1, _("%s: compression"), desc);
+	struct dpkg_error err;
+
+	if (fd_fd_copy(fd_in, fd_out, -1, &err) < 0)
+		ohshit(_("%s: pass-through copy error: %s"), desc, err.str);
 }
 
 static const struct compressor compressor_none = {

+ 2 - 2
lib/dpkg/test/t-buffer.c

@@ -60,13 +60,13 @@ test_fdio_hash(void)
 	fd = mkstemp(test_file);
 	test_pass(fd >= 0);
 
-	fd_md5(fd, hash, -1, "test empty file");
+	test_pass(fd_md5(fd, hash, -1, NULL) >= 0);
 	test_str(hash, ==, ref_hash_empty);
 
 	test_pass(write(fd, str_test, strlen(str_test)) == strlen(str_test));
 	test_pass(lseek(fd, 0, SEEK_SET) == 0);
 
-	fd_md5(fd, hash, -1, "test filled file");
+	test_pass(fd_md5(fd, hash, -1, NULL) >= 0);
 	test_str(hash, ==, ref_hash_test);
 
 	test_pass(unlink(test_file) == 0);

+ 20 - 12
src/archives.c

@@ -236,12 +236,15 @@ int tarfileread(void *ud, char *buf, int len) {
 static void
 tarobject_skip_padding(struct tarcontext *tc, struct tar_entry *te)
 {
+  struct dpkg_error err;
   size_t r;
 
   r = te->size % TARBLKSZ;
-  if (r > 0)
-    fd_skip(tc->backendpipe, TARBLKSZ - r,
-            _("error reading from dpkg-deb pipe"));
+  if (r == 0)
+    return;
+
+  if (fd_skip(tc->backendpipe, TARBLKSZ - r, &err) < 0)
+    ohshit(_("cannot skip padding for file '%.255s': %s"), te->name, err.str);
 }
 
 static void
@@ -250,11 +253,12 @@ tarobject_skip_entry(struct tarcontext *tc, struct tar_entry *ti)
   /* We need to advance the tar file to the next object, so read the
    * file data and set it to oblivion. */
   if (ti->type == tar_filetype_file) {
+    struct dpkg_error err;
     char fnamebuf[256];
 
-    fd_skip(tc->backendpipe, ti->size,
-            _("skipped unpacking file '%.255s' (replaced or excluded?)"),
-            path_quote_filename(fnamebuf, ti->name, 256));
+    if (fd_skip(tc->backendpipe, ti->size, &err) < 0)
+      ohshit(_("cannot skip file '%.255s' (replaced or excluded?) from pipe: %s"),
+             path_quote_filename(fnamebuf, ti->name, 256), err.str);
     tarobject_skip_padding(tc, ti);
   }
 }
@@ -303,8 +307,10 @@ tarobject_extract(struct tarcontext *tc, struct tar_entry *te,
   static struct varbuf hardlinkfn;
   static int fd;
 
+  struct dpkg_error err;
   struct filenamenode *linknode;
   char fnamebuf[256];
+  char fnamenewbuf[256];
   char *newhash;
 
   switch (te->type) {
@@ -320,9 +326,10 @@ tarobject_extract(struct tarcontext *tc, struct tar_entry *te,
           (intmax_t)te->size);
 
     newhash = nfmalloc(MD5HASHLEN + 1);
-    fd_fd_copy_and_md5(tc->backendpipe, fd, newhash, te->size,
-                       _("backend dpkg-deb during `%.255s'"),
-                       path_quote_filename(fnamebuf, te->name, 256));
+    if (fd_fd_copy_and_md5(tc->backendpipe, fd, newhash, te->size, &err) < 0)
+      ohshit(_("cannot copy extracted data for '%.255s' to '%.255s': %s"),
+             path_quote_filename(fnamebuf, te->name, 256),
+             path_quote_filename(fnamenewbuf, fnamenewvb.buf, 256), err.str);
     namenode->newhash = newhash;
     debug(dbg_eachfiledetail, "tarobject file hash=%s", namenode->newhash);
 
@@ -400,13 +407,14 @@ tarobject_hash(struct tarcontext *tc, struct tar_entry *te,
                struct filenamenode *namenode)
 {
   if (te->type == tar_filetype_file) {
+    struct dpkg_error err;
     char fnamebuf[256];
     char *newhash;
 
     newhash = nfmalloc(MD5HASHLEN + 1);
-    fd_md5(tc->backendpipe, newhash, te->size,
-           _("backend dpkg-deb during `%.255s'"),
-           path_quote_filename(fnamebuf, te->name, 256));
+    if (fd_md5(tc->backendpipe, newhash, te->size, &err) < 0)
+      ohshit(_("cannot compute MD5 hash for tar file '%.255s': %s"),
+             path_quote_filename(fnamebuf, te->name, 256), err.str);
     tarobject_skip_padding(tc, te);
 
     namenode->newhash = newhash;

+ 4 - 1
src/configure.c

@@ -535,13 +535,16 @@ conffderef(struct pkginfo *pkg, struct varbuf *result, const char *in)
 void
 md5hash(struct pkginfo *pkg, char *hashbuf, const char *fn)
 {
+	struct dpkg_error err;
 	static int fd;
 
 	fd = open(fn, O_RDONLY);
 
 	if (fd >= 0) {
 		push_cleanup(cu_closefd, ehflag_bombout, NULL, 0, 1, &fd);
-		fd_md5(fd, hashbuf, -1, _("md5hash"));
+		if (fd_md5(fd, hashbuf, -1, &err) < 0)
+			ohshit(_("cannot compute MD5 hash for file '%s': %s"),
+			       fn, err.str);
 		pop_cleanup(ehflag_normaltidy); /* fd = open(cdr.buf) */
 		close(fd);
 	} else if (errno == ENOENT) {

+ 3 - 1
src/divertcmd.c

@@ -208,6 +208,7 @@ check_rename(struct file *src, struct file *dst)
 static void
 file_copy(const char *src, const char *realdst)
 {
+	struct dpkg_error err;
 	char *dst;
 	int srcfd, dstfd;
 
@@ -222,7 +223,8 @@ file_copy(const char *src, const char *realdst)
 
 	/* FIXME: leaves a dangling destination file on error. */
 
-	fd_fd_copy(srcfd, dstfd, -1, _("file copy"));
+	if (fd_fd_copy(srcfd, dstfd, -1, &err) < 0)
+		ohshit(_("cannot copy '%s' to '%s': %s"), src, dst, err.str);
 
 	close(srcfd);
 

+ 3 - 1
src/processarc.c

@@ -422,6 +422,7 @@ void process_archive(const char *filename) {
   static struct varbuf depprobwhy;
   static struct tarcontext tc;
 
+  struct dpkg_error err;
   enum parsedbflags parsedb_flags;
   int r, i;
   pid_t pid;
@@ -927,7 +928,8 @@ void process_archive(const char *filename) {
       ohshit(_("corrupted filesystem tarfile - corrupted package archive"));
     }
   }
-  fd_skip(p1[0], -1, _("dpkg-deb: zap possible trailing zeros"));
+  if (fd_skip(p1[0], -1, &err) < 0)
+    ohshit(_("cannot zap possible trailing zeros from dpkg-deb: %s"), err.str);
   close(p1[0]);
   p1[0] = -1;
   subproc_wait_check(pid, BACKEND " --fsys-tarfile", PROCPIPE);