summaryrefslogtreecommitdiff
path: root/archivers/gcpio
diff options
context:
space:
mode:
authorseb <seb>2006-02-12 01:44:28 +0000
committerseb <seb>2006-02-12 01:44:28 +0000
commitc1018c2df9c2dd9fd3b533307b73b54583b44042 (patch)
tree579c469e77952aa95211daaab3c7a77082282d7d /archivers/gcpio
parent6780c97db0cd49379fc3a3ad9b531914ce60c36f (diff)
downloadpkgsrc-c1018c2df9c2dd9fd3b533307b73b54583b44042.tar.gz
Security fix for http://secunia.com/advisories/18251/ (CVE-2005-4268)
adapted from patch attached in redhat bugzilla https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=172669 While here add test target support. Bump PKGREVISION to 2.
Diffstat (limited to 'archivers/gcpio')
-rw-r--r--archivers/gcpio/Makefile6
-rw-r--r--archivers/gcpio/distinfo5
-rw-r--r--archivers/gcpio/patches/patch-ak13
-rw-r--r--archivers/gcpio/patches/patch-ap549
4 files changed, 567 insertions, 6 deletions
diff --git a/archivers/gcpio/Makefile b/archivers/gcpio/Makefile
index 849f0a91e7a..31a4f143532 100644
--- a/archivers/gcpio/Makefile
+++ b/archivers/gcpio/Makefile
@@ -1,8 +1,8 @@
-# $NetBSD: Makefile,v 1.28 2005/12/05 23:55:01 rillig Exp $
+# $NetBSD: Makefile,v 1.29 2006/02/12 01:44:28 seb Exp $
#
DISTNAME= cpio-2.6
-PKGREVISION= 1
+PKGREVISION= 2
PKGNAME= g${DISTNAME}
CATEGORIES= archivers
MASTER_SITES= ${MASTER_SITE_GNU:=cpio/}
@@ -16,6 +16,8 @@ PKG_INSTALLATION_TYPES= overwrite pkgviews
GNU_CONFIGURE= yes
USE_MAKEINFO= yes
+TEST_TARGET= check
+
INFO_FILES= cpio.info
.include "../../mk/bsd.prefs.mk"
diff --git a/archivers/gcpio/distinfo b/archivers/gcpio/distinfo
index 89a0f90ab80..040e609b5b5 100644
--- a/archivers/gcpio/distinfo
+++ b/archivers/gcpio/distinfo
@@ -1,4 +1,4 @@
-$NetBSD: distinfo,v 1.9 2005/11/03 19:38:51 adrianp Exp $
+$NetBSD: distinfo,v 1.10 2006/02/12 01:44:28 seb Exp $
SHA1 (cpio-2.6.tar.gz) = 5a4ea156519909994fe05933dc823abcf07e3e21
RMD160 (cpio-2.6.tar.gz) = 8246bdd08ab8727f9a8042d33ddfe3a6332476b8
@@ -9,8 +9,9 @@ SHA1 (patch-ag) = 04364ee26f2301f6ddefd2a2bc2b1fff3686411f
SHA1 (patch-ah) = f7e17682c2f6783e72310ef1d82a1bfca376e5ce
SHA1 (patch-ai) = c3ad35aa4fe9c82e5110c52c61ca3405915e19ab
SHA1 (patch-aj) = 1a4f796692cdad64297590acea33f371c903fa66
-SHA1 (patch-ak) = fb1a4d78901b419e370609e28efe67bdb72cdbd5
+SHA1 (patch-ak) = 9f795bf2f600ec31cf760ea0e5a0fc1c014fd143
SHA1 (patch-al) = 3c1e71ad7a10c80e8ec82718ee44d138641eb18e
SHA1 (patch-am) = d380ee141b218c568abc69ad90def03add91cde5
SHA1 (patch-an) = 943fe81aba7846bd8349cc2e31ab9525e019e99f
SHA1 (patch-ao) = 53c7b6bc1e00a0203665e12807b3388204f838c3
+SHA1 (patch-ap) = cf1ca21394e4e437e64fc83837e08b0aba26d41e
diff --git a/archivers/gcpio/patches/patch-ak b/archivers/gcpio/patches/patch-ak
index a2084ddda05..6ca5e745359 100644
--- a/archivers/gcpio/patches/patch-ak
+++ b/archivers/gcpio/patches/patch-ak
@@ -1,6 +1,6 @@
-$NetBSD: patch-ak,v 1.1 2005/11/03 19:38:50 adrianp Exp $
+$NetBSD: patch-ak,v 1.2 2006/02/12 01:44:28 seb Exp $
---- src/extern.h.orig 2004-09-08 11:49:57.000000000 +0100
+--- src/extern.h.orig 2004-09-08 12:49:57.000000000 +0200
+++ src/extern.h
@@ -46,7 +46,7 @@ extern int no_chown_flag;
extern int sparse_flag;
@@ -11,3 +11,12 @@ $NetBSD: patch-ak,v 1.1 2005/11/03 19:38:50 adrianp Exp $
extern unsigned int warn_option;
/* Values for warn_option */
+@@ -112,7 +112,7 @@ void long_format P_((struct new_cpio_hea
+ void print_name_with_quoting P_((char *p));
+
+ /* copyout.c */
+-void write_out_header P_((struct new_cpio_header *file_hdr, int out_des));
++int write_out_header P_((struct new_cpio_header *file_hdr, int out_des));
+ void process_copy_out P_((void));
+
+ /* copypass.c */
diff --git a/archivers/gcpio/patches/patch-ap b/archivers/gcpio/patches/patch-ap
new file mode 100644
index 00000000000..49b3502ae8e
--- /dev/null
+++ b/archivers/gcpio/patches/patch-ap
@@ -0,0 +1,549 @@
+$NetBSD: patch-ap,v 1.1 2006/02/12 01:44:28 seb Exp $
+
+--- src/copyout.c.orig 2004-10-14 09:14:03.000000000 +0000
++++ src/copyout.c
+@@ -159,7 +159,7 @@ add_link_defer (struct new_cpio_header *
+ }
+
+ /* We are about to put a file into a newc or crc archive that is
+- multiply linked. We have already seen and defered all of the
++ multiply linked. We have already seen and deferred all of the
+ other links to the file but haven't written them into the archive.
+ Write the other links into the archive, and remove them from the
+ deferouts list. */
+@@ -231,8 +231,10 @@ writeout_defered_file (struct new_cpio_h
+ file_hdr.c_filesize,
+ header->c_name);
+
+- write_out_header (&file_hdr, out_file_des);
+- copy_files_disk_to_tape (in_file_des, out_file_des, file_hdr.c_filesize, header->c_name);
++ if (write_out_header (&file_hdr, out_file_des))
++ return;
++ copy_files_disk_to_tape (in_file_des, out_file_des, file_hdr.c_filesize,
++ header->c_name);
+ warn_if_file_changed(header->c_name, file_hdr.c_filesize, file_hdr.c_mtime);
+
+ if (archive_format == arf_tar || archive_format == arf_ustar)
+@@ -288,153 +290,313 @@ writeout_final_defers (int out_des)
+ }
+ }
+
+-
+-/* Write out header FILE_HDR, including the file name, to file
+- descriptor OUT_DES. */
++/* FIXME: These two defines should be defined in paxutils */
++#define LG_8 3
++#define LG_16 4
++
++/* FIXME: to_ascii could be used instead of to_oct() and to_octal() from tar,
++ so it should be moved to paxutils too.
++ Allowed values for logbase are: 1 (binary), 2, 3 (octal), 4 (hex) */
++int
++to_ascii (char *where, uintmax_t v, size_t digits, unsigned logbase)
++{
++ static char codetab[] = "0123456789ABCDEF";
++ int i = digits;
++
++ do
++ {
++ where[--i] = codetab[(v & ((1 << logbase) - 1))];
++ v >>= logbase;
++ }
++ while (i);
++
++ return v != 0;
++}
++
++static void
++field_width_error (const char *filename, const char *fieldname)
++{
++ error (0, 0, _("%s: field width not sufficient for storing %s"),
++ filename, fieldname);
++}
++
++static void
++field_width_warning (const char *filename, const char *fieldname)
++{
++ if (warn_option & CPIO_WARN_TRUNCATE)
++ error (0, 0, _("%s: truncating %s"), filename, fieldname);
++}
+
+ void
+-write_out_header (struct new_cpio_header *file_hdr, int out_des)
++to_ascii_or_warn (char *where, uintmax_t n, size_t digits,
++ unsigned logbase,
++ const char *filename, const char *fieldname)
+ {
+- if (archive_format == arf_newascii || archive_format == arf_crcascii)
++ if (to_ascii (where, n, digits, logbase))
++ field_width_warning (filename, fieldname);
++}
++
++int
++to_ascii_or_error (char *where, uintmax_t n, size_t digits,
++ unsigned logbase,
++ const char *filename, const char *fieldname)
++{
++ if (to_ascii (where, n, digits, logbase))
+ {
+- char ascii_header[112];
+- char *magic_string;
++ field_width_error (filename, fieldname);
++ return 1;
++ }
++ return 0;
++}
+
+- if (archive_format == arf_crcascii)
+- magic_string = "070702";
+- else
+- magic_string = "070701";
+- sprintf (ascii_header,
+- "%6s%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx",
+- magic_string,
+- file_hdr->c_ino, file_hdr->c_mode, file_hdr->c_uid,
+- file_hdr->c_gid, file_hdr->c_nlink, file_hdr->c_mtime,
+- file_hdr->c_filesize, file_hdr->c_dev_maj, file_hdr->c_dev_min,
+- file_hdr->c_rdev_maj, file_hdr->c_rdev_min, file_hdr->c_namesize,
+- file_hdr->c_chksum);
+- tape_buffered_write (ascii_header, out_des, 110L);
+-
+- /* Write file name to output. */
+- tape_buffered_write (file_hdr->c_name, out_des, (long) file_hdr->c_namesize);
+- tape_pad_output (out_des, file_hdr->c_namesize + 110);
+- }
+- else if (archive_format == arf_oldascii || archive_format == arf_hpoldascii)
+- {
+- char ascii_header[78];
+- dev_t dev;
+- dev_t rdev;
++int
++write_out_new_ascii_header (const char *magic_string,
++ struct new_cpio_header *file_hdr, int out_des)
++{
++ char ascii_header[110];
++ char *p;
+
+- if (archive_format == arf_oldascii)
+- {
+- dev = makedev (file_hdr->c_dev_maj, file_hdr->c_dev_min);
+- rdev = makedev (file_hdr->c_rdev_maj, file_hdr->c_rdev_min);
+- }
+- else
+- {
+- /* HP/UX cpio creates archives that look just like ordinary archives,
+- but for devices it sets major = 0, minor = 1, and puts the
+- actual major/minor number in the filesize field. */
+- switch (file_hdr->c_mode & CP_IFMT)
+- {
+- case CP_IFCHR:
+- case CP_IFBLK:
++ (void)strncpy(ascii_header, magic_string, sizeof(ascii_header) - 1);
++ ascii_header[sizeof(ascii_header) -1] = '\0';
++ p = ascii_header + strlen(ascii_header);
++ to_ascii_or_warn (p, file_hdr->c_ino, 8, LG_16,
++ file_hdr->c_name, _("inode number"));
++ p += 8;
++ to_ascii_or_warn (p, file_hdr->c_mode, 8, LG_16, file_hdr->c_name,
++ _("file mode"));
++ p += 8;
++ to_ascii_or_warn (p, file_hdr->c_uid, 8, LG_16, file_hdr->c_name,
++ _("uid"));
++ p += 8;
++ to_ascii_or_warn (p, file_hdr->c_gid, 8, LG_16, file_hdr->c_name,
++ _("gid"));
++ p += 8;
++ to_ascii_or_warn (p, file_hdr->c_nlink, 8, LG_16, file_hdr->c_name,
++ _("number of links"));
++ p += 8;
++ to_ascii_or_warn (p, file_hdr->c_mtime, 8, LG_16, file_hdr->c_name,
++ _("modification time"));
++ p += 8;
++ if (to_ascii_or_error (p, file_hdr->c_filesize, 8, LG_16, file_hdr->c_name,
++ _("file size")))
++ return 1;
++ p += 8;
++ if (to_ascii_or_error (p, file_hdr->c_dev_maj, 8, LG_16, file_hdr->c_name,
++ _("device major number")))
++ return 1;
++ p += 8;
++ if (to_ascii_or_error (p, file_hdr->c_dev_min, 8, LG_16, file_hdr->c_name,
++ _("device minor number")))
++ return 1;
++ p += 8;
++ if (to_ascii_or_error (p, file_hdr->c_rdev_maj, 8, LG_16, file_hdr->c_name,
++ _("rdev major")))
++ return 1;
++ p += 8;
++ if (to_ascii_or_error (p, file_hdr->c_rdev_min, 8, LG_16, file_hdr->c_name,
++ _("rdev minor")))
++ return 1;
++ p += 8;
++ if (to_ascii_or_error (p, file_hdr->c_namesize, 8, LG_16, file_hdr->c_name,
++ _("name size")))
++ return 1;
++ p += 8;
++ to_ascii (p, file_hdr->c_chksum & 0xffffffff, 8, LG_16);
++
++ tape_buffered_write (ascii_header, out_des, sizeof ascii_header);
++
++ /* Write file name to output. */
++ tape_buffered_write (file_hdr->c_name, out_des, (long) file_hdr->c_namesize);
++ tape_pad_output (out_des, file_hdr->c_namesize + sizeof ascii_header);
++ return 0;
++}
++
++int
++write_out_old_ascii_header (dev_t dev, dev_t rdev,
++ struct new_cpio_header *file_hdr, int out_des)
++{
++ char ascii_header[76];
++ char *p = ascii_header;
++
++ to_ascii (p, file_hdr->c_magic, 6, LG_8);
++ p += 6;
++ to_ascii_or_warn (p, dev, 6, LG_8, file_hdr->c_name, _("device number"));
++ p += 6;
++ to_ascii_or_warn (p, file_hdr->c_ino, 6, LG_8, file_hdr->c_name,
++ _("inode number"));
++ p += 6;
++ to_ascii_or_warn (p, file_hdr->c_mode, 6, LG_8, file_hdr->c_name,
++ _("file mode"));
++ p += 6;
++ to_ascii_or_warn (p, file_hdr->c_uid, 6, LG_8, file_hdr->c_name, _("uid"));
++ p += 6;
++ to_ascii_or_warn (p, file_hdr->c_gid, 6, LG_8, file_hdr->c_name, _("gid"));
++ p += 6;
++ to_ascii_or_warn (p, file_hdr->c_nlink, 6, LG_8, file_hdr->c_name,
++ _("number of links"));
++ p += 6;
++ to_ascii_or_warn (p, rdev, 6, LG_8, file_hdr->c_name, _("rdev"));
++ p += 6;
++ to_ascii_or_warn (p, file_hdr->c_mtime, 11, LG_8, file_hdr->c_name,
++ _("modification time"));
++ p += 11;
++ if (to_ascii_or_error (p, file_hdr->c_namesize, 6, LG_8, file_hdr->c_name,
++ _("name size")))
++ return 1;
++ p += 6;
++ if (to_ascii_or_error (p, file_hdr->c_filesize, 11, LG_8, file_hdr->c_name,
++ _("file size")))
++ return 1;
++
++ tape_buffered_write (ascii_header, out_des, sizeof ascii_header);
++
++ /* Write file name to output. */
++ tape_buffered_write (file_hdr->c_name, out_des, file_hdr->c_namesize);
++ return 0;
++}
++
++void
++hp_compute_dev (struct new_cpio_header *file_hdr, dev_t *pdev, dev_t *prdev)
++{
++ /* HP/UX cpio creates archives that look just like ordinary archives,
++ but for devices it sets major = 0, minor = 1, and puts the
++ actual major/minor number in the filesize field. */
++ switch (file_hdr->c_mode & CP_IFMT)
++ {
++ case CP_IFCHR:
++ case CP_IFBLK:
+ #ifdef CP_IFSOCK
+- case CP_IFSOCK:
++ case CP_IFSOCK:
+ #endif
+ #ifdef CP_IFIFO
+- case CP_IFIFO:
++ case CP_IFIFO:
+ #endif
+- file_hdr->c_filesize = makedev (file_hdr->c_rdev_maj,
+- file_hdr->c_rdev_min);
+- rdev = 1;
+- break;
+- default:
+- dev = makedev (file_hdr->c_dev_maj, file_hdr->c_dev_min);
+- rdev = makedev (file_hdr->c_rdev_maj, file_hdr->c_rdev_min);
+- break;
+- }
+- }
++ file_hdr->c_filesize = makedev (file_hdr->c_rdev_maj,
++ file_hdr->c_rdev_min);
++ *pdev = *prdev = makedev (0, 1);
++ break;
++
++ default:
++ *pdev = makedev (file_hdr->c_dev_maj, file_hdr->c_dev_min);
++ *prdev = makedev (file_hdr->c_rdev_maj, file_hdr->c_rdev_min);
++ break;
++ }
++}
+
+- if ((warn_option & CPIO_WARN_TRUNCATE) && (file_hdr->c_ino >> 16) != 0)
+- error (0, 0, _("%s: truncating inode number"), file_hdr->c_name);
++int
++write_out_binary_header (dev_t rdev,
++ struct new_cpio_header *file_hdr, int out_des)
++{
++ struct old_cpio_header short_hdr;
+
+- /* Debian hack: The type of dev_t has changed in glibc. Fixed output
+- to ensure that a long int is passed to sprintf. This has been
+- reported to "bug-gnu-utils@prep.ai.mit.edu". (1998/5/26) -BEM */
+- sprintf (ascii_header,
+- "%06ho%06lo%06lo%06lo%06lo%06lo%06lo%06lo%011lo%06lo%011lo",
+- file_hdr->c_magic & 0xFFFF, (long) dev & 0xFFFF,
+- file_hdr->c_ino & 0xFFFF, file_hdr->c_mode & 0xFFFF,
+- file_hdr->c_uid & 0xFFFF, file_hdr->c_gid & 0xFFFF,
+- file_hdr->c_nlink & 0xFFFF, (long) rdev & 0xFFFF,
+- file_hdr->c_mtime, file_hdr->c_namesize & 0xFFFF,
+- file_hdr->c_filesize);
+- tape_buffered_write (ascii_header, out_des, 76L);
++ short_hdr.c_magic = 070707;
++ short_hdr.c_dev = makedev (file_hdr->c_dev_maj, file_hdr->c_dev_min);
+
+- /* Write file name to output. */
+- tape_buffered_write (file_hdr->c_name, out_des, (long) file_hdr->c_namesize);
+- }
+- else if (archive_format == arf_tar || archive_format == arf_ustar)
+- {
+- write_out_tar_header (file_hdr, out_des);
+- }
+- else
+- {
+- struct old_cpio_header short_hdr;
++ if ((warn_option & CPIO_WARN_TRUNCATE) && (file_hdr->c_ino >> 16) != 0)
++ error (0, 0, _("%s: truncating inode number"), file_hdr->c_name);
+
+- short_hdr.c_magic = 070707;
+- short_hdr.c_dev = makedev (file_hdr->c_dev_maj, file_hdr->c_dev_min);
++ short_hdr.c_ino = file_hdr->c_ino & 0xFFFF;
++ if (short_hdr.c_ino != file_hdr->c_ino)
++ field_width_warning (file_hdr->c_name, _("inode number"));
++
++ short_hdr.c_mode = file_hdr->c_mode & 0xFFFF;
++ if (short_hdr.c_mode != file_hdr->c_mode)
++ field_width_warning (file_hdr->c_name, _("file mode"));
++
++ short_hdr.c_uid = file_hdr->c_uid & 0xFFFF;
++ if (short_hdr.c_uid != file_hdr->c_uid)
++ field_width_warning (file_hdr->c_name, _("uid"));
++
++ short_hdr.c_gid = file_hdr->c_gid & 0xFFFF;
++ if (short_hdr.c_gid != file_hdr->c_gid)
++ field_width_warning (file_hdr->c_name, _("gid"));
++
++ short_hdr.c_nlink = file_hdr->c_nlink & 0xFFFF;
++ if (short_hdr.c_nlink != file_hdr->c_nlink)
++ field_width_warning (file_hdr->c_name, _("number of links"));
++
++ short_hdr.c_rdev = rdev;
++ short_hdr.c_mtimes[0] = file_hdr->c_mtime >> 16;
++ short_hdr.c_mtimes[1] = file_hdr->c_mtime & 0xFFFF;
++
++ short_hdr.c_namesize = file_hdr->c_namesize & 0xFFFF;
++ if (short_hdr.c_namesize != file_hdr->c_namesize)
++ {
++ field_width_error (file_hdr->c_name, _("name size"));
++ return 1;
++ }
++
++ short_hdr.c_filesize = file_hdr->c_filesize;
++ if (short_hdr.c_filesize != file_hdr->c_filesize)
++ {
++ field_width_error (file_hdr->c_name, _("file size"));
++ return 1;
++ }
++
++ short_hdr.c_filesizes[0] = file_hdr->c_filesize >> 16;
++ short_hdr.c_filesizes[1] = file_hdr->c_filesize & 0xFFFF;
+
+- if ((warn_option & CPIO_WARN_TRUNCATE) && (file_hdr->c_ino >> 16) != 0)
+- error (0, 0, _("%s: truncating inode number"), file_hdr->c_name);
++ /* Output the file header. */
++ tape_buffered_write ((char *) &short_hdr, out_des, 26);
+
+- short_hdr.c_ino = file_hdr->c_ino & 0xFFFF;
+- short_hdr.c_mode = file_hdr->c_mode & 0xFFFF;
+- short_hdr.c_uid = file_hdr->c_uid & 0xFFFF;
+- short_hdr.c_gid = file_hdr->c_gid & 0xFFFF;
+- short_hdr.c_nlink = file_hdr->c_nlink & 0xFFFF;
+- if (archive_format != arf_hpbinary)
+- short_hdr.c_rdev = makedev (file_hdr->c_rdev_maj, file_hdr->c_rdev_min);
+- else
+- {
+- switch (file_hdr->c_mode & CP_IFMT)
+- {
+- /* HP/UX cpio creates archives that look just like ordinary
+- archives, but for devices it sets major = 0, minor = 1, and
+- puts the actual major/minor number in the filesize field. */
+- case CP_IFCHR:
+- case CP_IFBLK:
+-#ifdef CP_IFSOCK
+- case CP_IFSOCK:
+-#endif
+-#ifdef CP_IFIFO
+- case CP_IFIFO:
+-#endif
+- file_hdr->c_filesize = makedev (file_hdr->c_rdev_maj,
+- file_hdr->c_rdev_min);
+- short_hdr.c_rdev = makedev (0, 1);
+- break;
+- default:
+- short_hdr.c_rdev = makedev (file_hdr->c_rdev_maj,
+- file_hdr->c_rdev_min);
+- break;
+- }
+- }
+- short_hdr.c_mtimes[0] = file_hdr->c_mtime >> 16;
+- short_hdr.c_mtimes[1] = file_hdr->c_mtime & 0xFFFF;
++ /* Write file name to output. */
++ tape_buffered_write (file_hdr->c_name, out_des, file_hdr->c_namesize);
+
+- short_hdr.c_namesize = file_hdr->c_namesize & 0xFFFF;
++ tape_pad_output (out_des, file_hdr->c_namesize + 26);
++ return 0;
++}
+
+- short_hdr.c_filesizes[0] = file_hdr->c_filesize >> 16;
+- short_hdr.c_filesizes[1] = file_hdr->c_filesize & 0xFFFF;
++
++/* Write out header FILE_HDR, including the file name, to file
++ descriptor OUT_DES. */
+
+- /* Output the file header. */
+- tape_buffered_write ((char *) &short_hdr, out_des, 26L);
++int
++write_out_header (struct new_cpio_header *file_hdr, int out_des)
++{
++ dev_t dev;
++ dev_t rdev;
++
++ switch (archive_format)
++ {
++ case arf_newascii:
++ return write_out_new_ascii_header ("070701", file_hdr, out_des);
++
++ case arf_crcascii:
++ return write_out_new_ascii_header ("070702", file_hdr, out_des);
++
++ case arf_oldascii:
++ return write_out_old_ascii_header (makedev (file_hdr->c_dev_maj,
++ file_hdr->c_dev_min),
++ makedev (file_hdr->c_rdev_maj,
++ file_hdr->c_rdev_min),
++ file_hdr, out_des);
++
++ case arf_hpoldascii:
++ hp_compute_dev (file_hdr, &dev, &rdev);
++ return write_out_old_ascii_header (dev, rdev, file_hdr, out_des);
++
++ case arf_tar:
++ case arf_ustar:
++ if (is_tar_filename_too_long (file_hdr->c_name))
++ {
++ error (0, 0, _("%s: file name too long"), file_hdr->c_name);
++ return 1;
++ }
++ write_out_tar_header (file_hdr, out_des); /* FIXME: No error checking */
++ return 0;
+
+- /* Write file name to output. */
+- tape_buffered_write (file_hdr->c_name, out_des, (long) file_hdr->c_namesize);
++ case arf_binary:
++ return write_out_binary_header (makedev (file_hdr->c_rdev_maj,
++ file_hdr->c_rdev_min),
++ file_hdr, out_des);
++
++ case arf_hpbinary:
++ hp_compute_dev (file_hdr, &dev, &rdev);
++ /* FIXME: dev ignored. Should it be? */
++ return write_out_binary_header (rdev, file_hdr, out_des);
+
+- tape_pad_output (out_des, file_hdr->c_namesize + 26);
++ default:
++ abort ();
+ }
+ }
+
+@@ -593,14 +755,7 @@ process_copy_out ()
+ file_hdr.c_namesize = strlen (p) + 1;
+ }
+ #endif
+- if ((archive_format == arf_tar || archive_format == arf_ustar)
+- && is_tar_filename_too_long (file_hdr.c_name))
+- {
+- error (0, 0, _("%s: file name too long"),
+- file_hdr.c_name);
+- continue;
+- }
+-
++
+ /* Copy the named file to the output. */
+ switch (file_hdr.c_mode & CP_IFMT)
+ {
+@@ -613,8 +768,8 @@ process_copy_out ()
+ file_hdr.c_dev_min)))
+ {
+ file_hdr.c_tar_linkname = otherfile;
+- write_out_header (&file_hdr, out_file_des);
+- break;
++ if (write_out_header (&file_hdr, out_file_des))
++ continue;
+ }
+ }
+ if ( (archive_format == arf_newascii || archive_format == arf_crcascii)
+@@ -643,7 +798,8 @@ process_copy_out ()
+ file_hdr.c_filesize,
+ input_name.ds_string);
+
+- write_out_header (&file_hdr, out_file_des);
++ if (write_out_header (&file_hdr, out_file_des))
++ continue;
+ copy_files_disk_to_tape (in_file_des, out_file_des, file_hdr.c_filesize, input_name.ds_string);
+ warn_if_file_changed(input_name.ds_string, file_hdr.c_filesize,
+ file_hdr.c_mtime);
+@@ -673,7 +829,8 @@ process_copy_out ()
+
+ case CP_IFDIR:
+ file_hdr.c_filesize = 0;
+- write_out_header (&file_hdr, out_file_des);
++ if (write_out_header (&file_hdr, out_file_des))
++ continue;
+ break;
+
+ case CP_IFCHR:
+@@ -702,14 +859,16 @@ process_copy_out ()
+ file_hdr.c_mode = (file_stat.st_mode & 07777);
+ file_hdr.c_mode |= CP_IFREG;
+ file_hdr.c_tar_linkname = otherfile;
+- write_out_header (&file_hdr, out_file_des);
++ if (write_out_header (&file_hdr, out_file_des))
++ continue;
+ break;
+ }
+ add_inode (file_hdr.c_ino, file_hdr.c_name,
+ file_hdr.c_dev_maj, file_hdr.c_dev_min);
+ }
+ file_hdr.c_filesize = 0;
+- write_out_header (&file_hdr, out_file_des);
++ if (write_out_header (&file_hdr, out_file_des))
++ continue;
+ break;
+
+ #ifdef CP_IFLNK
+@@ -738,12 +897,14 @@ process_copy_out ()
+ {
+ link_name[link_size] = '\0';
+ file_hdr.c_tar_linkname = link_name;
+- write_out_header (&file_hdr, out_file_des);
++ if (write_out_header (&file_hdr, out_file_des))
++ continue;
+ }
+ }
+ else
+ {
+- write_out_header (&file_hdr, out_file_des);
++ if (write_out_header (&file_hdr, out_file_des))
++ continue;
+ tape_buffered_write (link_name, out_file_des, link_size);
+ tape_pad_output (out_file_des, link_size);
+ }