Home | History | Annotate | Line # | Download | only in pax
cpio.c revision 1.7
      1 /*	$NetBSD: cpio.c,v 1.7 1997/07/20 20:32:24 christos Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 1992 Keith Muller.
      5  * Copyright (c) 1992, 1993
      6  *	The Regents of the University of California.  All rights reserved.
      7  *
      8  * This code is derived from software contributed to Berkeley by
      9  * Keith Muller of the University of California, San Diego.
     10  *
     11  * Redistribution and use in source and binary forms, with or without
     12  * modification, are permitted provided that the following conditions
     13  * are met:
     14  * 1. Redistributions of source code must retain the above copyright
     15  *    notice, this list of conditions and the following disclaimer.
     16  * 2. Redistributions in binary form must reproduce the above copyright
     17  *    notice, this list of conditions and the following disclaimer in the
     18  *    documentation and/or other materials provided with the distribution.
     19  * 3. All advertising materials mentioning features or use of this software
     20  *    must display the following acknowledgement:
     21  *	This product includes software developed by the University of
     22  *	California, Berkeley and its contributors.
     23  * 4. Neither the name of the University nor the names of its contributors
     24  *    may be used to endorse or promote products derived from this software
     25  *    without specific prior written permission.
     26  *
     27  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     28  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     29  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     30  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     31  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     32  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     33  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     34  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     35  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     36  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     37  * SUCH DAMAGE.
     38  */
     39 
     40 #include <sys/cdefs.h>
     41 #ifndef lint
     42 #if 0
     43 static char sccsid[] = "@(#)cpio.c	8.1 (Berkeley) 5/31/93";
     44 #else
     45 __RCSID("$NetBSD: cpio.c,v 1.7 1997/07/20 20:32:24 christos Exp $");
     46 #endif
     47 #endif /* not lint */
     48 
     49 #include <sys/types.h>
     50 #include <sys/time.h>
     51 #include <sys/stat.h>
     52 #include <sys/param.h>
     53 #include <string.h>
     54 #include <ctype.h>
     55 #include <stdio.h>
     56 #include <unistd.h>
     57 #include <stdlib.h>
     58 #include "pax.h"
     59 #include "cpio.h"
     60 #include "extern.h"
     61 
     62 static int rd_nm __P((ARCHD *, int));
     63 static int rd_ln_nm __P((ARCHD *));
     64 static int com_rd __P((ARCHD *));
     65 
     66 /*
     67  * Routines which support the different cpio versions
     68  */
     69 
     70 static int swp_head;		/* binary cpio header byte swap */
     71 
     72 /*
     73  * Routines common to all versions of cpio
     74  */
     75 
     76 /*
     77  * cpio_strd()
     78  *	Fire up the hard link detection code
     79  * Return:
     80  *      0 if ok -1 otherwise (the return values of lnk_start())
     81  */
     82 
     83 #if __STDC__
     84 int
     85 cpio_strd(void)
     86 #else
     87 int
     88 cpio_strd()
     89 #endif
     90 {
     91 	return(lnk_start());
     92 }
     93 
     94 /*
     95  * cpio_subtrail()
     96  *	Called to determine if a header block is a valid trailer. We are
     97  *	passed the block, the in_sync flag (which tells us we are in resync
     98  *	mode; looking for a valid header), and cnt (which starts at zero)
     99  *	which is used to count the number of empty blocks we have seen so far.
    100  * Return:
    101  *	0 if a valid trailer, -1 if not a valid trailer,
    102  */
    103 
    104 #if __STDC__
    105 int
    106 cpio_subtrail(ARCHD *arcn)
    107 #else
    108 int
    109 cpio_subtrail(arcn)
    110 	ARCHD *arcn;
    111 #endif
    112 {
    113 	/*
    114 	 * look for trailer id in file we are about to process
    115 	 */
    116 	if ((strcmp(arcn->name, TRAILER) == 0) && (arcn->sb.st_size == 0))
    117 		return(0);
    118 	return(-1);
    119 }
    120 
    121 /*
    122  * com_rd()
    123  *	operations common to all cpio read functions.
    124  * Return:
    125  *	0
    126  */
    127 
    128 #if __STDC__
    129 static int
    130 com_rd(ARCHD *arcn)
    131 #else
    132 static int
    133 com_rd(arcn)
    134 	ARCHD *arcn;
    135 #endif
    136 {
    137 	arcn->skip = 0;
    138 	arcn->pat = NULL;
    139 	arcn->org_name = arcn->name;
    140 	switch(arcn->sb.st_mode & C_IFMT) {
    141 	case C_ISFIFO:
    142 		arcn->type = PAX_FIF;
    143 		break;
    144 	case C_ISDIR:
    145 		arcn->type = PAX_DIR;
    146 		break;
    147 	case C_ISBLK:
    148 		arcn->type = PAX_BLK;
    149 		break;
    150 	case C_ISCHR:
    151 		arcn->type = PAX_CHR;
    152 		break;
    153 	case C_ISLNK:
    154 		arcn->type = PAX_SLK;
    155 		break;
    156 	case C_ISOCK:
    157 		arcn->type = PAX_SCK;
    158 		break;
    159 	case C_ISCTG:
    160 	case C_ISREG:
    161 	default:
    162 		/*
    163 		 * we have file data, set up skip (pad is set in the format
    164 		 * specific sections)
    165 		 */
    166 		arcn->sb.st_mode = (arcn->sb.st_mode & 0xfff) | C_ISREG;
    167 		arcn->type = PAX_REG;
    168 		arcn->skip = arcn->sb.st_size;
    169 		break;
    170 	}
    171 	if (chk_lnk(arcn) < 0)
    172 		return(-1);
    173 	return(0);
    174 }
    175 
    176 /*
    177  * cpio_end_wr()
    178  *	write the special file with the name trailer in the proper format
    179  * Return:
    180  *	result of the write of the trailer from the cpio specific write func
    181  */
    182 
    183 #if __STDC__
    184 int
    185 cpio_endwr(void)
    186 #else
    187 int
    188 cpio_endwr()
    189 #endif
    190 {
    191 	ARCHD last;
    192 
    193 	/*
    194 	 * create a trailer request and call the proper format write function
    195 	 */
    196 	memset(&last, 0, sizeof(last));
    197 	last.nlen = sizeof(TRAILER) - 1;
    198 	last.type = PAX_REG;
    199 	last.sb.st_nlink = 1;
    200 	(void)strcpy(last.name, TRAILER);
    201 	return((*frmt->wr)(&last));
    202 }
    203 
    204 /*
    205  * rd_nam()
    206  *	read in the file name which follows the cpio header
    207  * Return:
    208  *	0 if ok, -1 otherwise
    209  */
    210 
    211 #if __STDC__
    212 static int
    213 rd_nm(ARCHD *arcn, int nsz)
    214 #else
    215 static int
    216 rd_nm(arcn, nsz)
    217 	ARCHD *arcn;
    218 	int nsz;
    219 #endif
    220 {
    221 	/*
    222 	 * do not even try bogus values
    223 	 */
    224 	if ((nsz == 0) || (nsz > sizeof(arcn->name))) {
    225 		tty_warn(1, "Cpio file name length %d is out of range", nsz);
    226 		return(-1);
    227 	}
    228 
    229 	/*
    230 	 * read the name and make sure it is not empty and is \0 terminated
    231 	 */
    232 	if ((rd_wrbuf(arcn->name,nsz) != nsz) || (arcn->name[nsz-1] != '\0') ||
    233 	    (arcn->name[0] == '\0')) {
    234 		tty_warn(1, "Cpio file name in header is corrupted");
    235 		return(-1);
    236 	}
    237 	return(0);
    238 }
    239 
    240 /*
    241  * rd_ln_nm()
    242  *	read in the link name for a file with links. The link name is stored
    243  *	like file data (and is NOT \0 terminated!)
    244  * Return:
    245  *	0 if ok, -1 otherwise
    246  */
    247 
    248 #if __STDC__
    249 static int
    250 rd_ln_nm(ARCHD *arcn)
    251 #else
    252 static int
    253 rd_ln_nm(arcn)
    254 	ARCHD *arcn;
    255 #endif
    256 {
    257 	/*
    258 	 * check the length specified for bogus values
    259 	 */
    260 	if ((arcn->sb.st_size == 0) ||
    261 	    (arcn->sb.st_size >= sizeof(arcn->ln_name))) {
    262 #		ifdef NET2_STAT
    263 		tty_warn(1, "Cpio link name length is invalid: %lu",
    264 		    arcn->sb.st_size);
    265 #		else
    266 		tty_warn(1, "Cpio link name length is invalid: %qu",
    267 		    (unsigned long long) arcn->sb.st_size);
    268 #		endif
    269 		return(-1);
    270 	}
    271 
    272 	/*
    273 	 * read in the link name and \0 terminate it
    274 	 */
    275 	if (rd_wrbuf(arcn->ln_name, (int)arcn->sb.st_size) !=
    276 	    (int)arcn->sb.st_size) {
    277 		tty_warn(1, "Cpio link name read error");
    278 		return(-1);
    279 	}
    280 	arcn->ln_nlen = arcn->sb.st_size;
    281 	arcn->ln_name[arcn->ln_nlen] = '\0';
    282 
    283 	/*
    284 	 * watch out for those empty link names
    285 	 */
    286 	if (arcn->ln_name[0] == '\0') {
    287 		tty_warn(1, "Cpio link name is corrupt");
    288 		return(-1);
    289 	}
    290 	return(0);
    291 }
    292 
    293 /*
    294  * Routines common to the extended byte oriented cpio format
    295  */
    296 
    297 /*
    298  * cpio_id()
    299  *      determine if a block given to us is a valid extended byte oriented
    300  *	cpio header
    301  * Return:
    302  *      0 if a valid header, -1 otherwise
    303  */
    304 
    305 #if __STDC__
    306 int
    307 cpio_id(char *blk, int size)
    308 #else
    309 int
    310 cpio_id(blk, size)
    311 	char *blk;
    312 	int size;
    313 #endif
    314 {
    315 	if ((size < sizeof(HD_CPIO)) ||
    316 	    (strncmp(blk, AMAGIC, sizeof(AMAGIC) - 1) != 0))
    317 		return(-1);
    318 	return(0);
    319 }
    320 
    321 /*
    322  * cpio_rd()
    323  *	determine if a buffer is a byte oriented extended cpio archive entry.
    324  *	convert and store the values in the ARCHD parameter.
    325  * Return:
    326  *	0 if a valid header, -1 otherwise.
    327  */
    328 
    329 #if __STDC__
    330 int
    331 cpio_rd(ARCHD *arcn, char *buf)
    332 #else
    333 int
    334 cpio_rd(arcn, buf)
    335 	ARCHD *arcn;
    336 	char *buf;
    337 #endif
    338 {
    339 	int nsz;
    340 	HD_CPIO *hd;
    341 
    342 	/*
    343 	 * check that this is a valid header, if not return -1
    344 	 */
    345 	if (cpio_id(buf, sizeof(HD_CPIO)) < 0)
    346 		return(-1);
    347 	hd = (HD_CPIO *)buf;
    348 
    349 	/*
    350 	 * byte oriented cpio (posix) does not have padding! extract the octal
    351 	 * ascii fields from the header
    352 	 */
    353 	arcn->pad = 0L;
    354 	arcn->sb.st_dev = (dev_t)asc_ul(hd->c_dev, sizeof(hd->c_dev), OCT);
    355 	arcn->sb.st_ino = (ino_t)asc_ul(hd->c_ino, sizeof(hd->c_ino), OCT);
    356 	arcn->sb.st_mode = (mode_t)asc_ul(hd->c_mode, sizeof(hd->c_mode), OCT);
    357 	arcn->sb.st_uid = (uid_t)asc_ul(hd->c_uid, sizeof(hd->c_uid), OCT);
    358 	arcn->sb.st_gid = (gid_t)asc_ul(hd->c_gid, sizeof(hd->c_gid), OCT);
    359 	arcn->sb.st_nlink = (nlink_t)asc_ul(hd->c_nlink, sizeof(hd->c_nlink),
    360 	    OCT);
    361 	arcn->sb.st_rdev = (dev_t)asc_ul(hd->c_rdev, sizeof(hd->c_rdev), OCT);
    362 	arcn->sb.st_mtime = (time_t)asc_ul(hd->c_mtime, sizeof(hd->c_mtime),
    363 	    OCT);
    364 	arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime;
    365 #	ifdef NET2_STAT
    366 	arcn->sb.st_size = (off_t)asc_ul(hd->c_filesize,sizeof(hd->c_filesize),
    367 	    OCT);
    368 #	else
    369 	arcn->sb.st_size = (off_t)asc_uqd(hd->c_filesize,sizeof(hd->c_filesize),
    370 	    OCT);
    371 #	endif
    372 
    373 	/*
    374 	 * check name size and if valid, read in the name of this entry (name
    375 	 * follows header in the archive)
    376 	 */
    377 	if ((nsz = (int)asc_ul(hd->c_namesize,sizeof(hd->c_namesize),OCT)) < 2)
    378 		return(-1);
    379 	arcn->nlen = nsz - 1;
    380 	if (rd_nm(arcn, nsz) < 0)
    381 		return(-1);
    382 
    383 	if (((arcn->sb.st_mode&C_IFMT) != C_ISLNK)||(arcn->sb.st_size == 0)) {
    384 		/*
    385 	 	 * no link name to read for this file
    386 	 	 */
    387 		arcn->ln_nlen = 0;
    388 		arcn->ln_name[0] = '\0';
    389 		return(com_rd(arcn));
    390 	}
    391 
    392 	/*
    393 	 * check link name size and read in the link name. Link names are
    394 	 * stored like file data.
    395 	 */
    396 	if (rd_ln_nm(arcn) < 0)
    397 		return(-1);
    398 
    399 	/*
    400 	 * we have a valid header (with a link)
    401 	 */
    402 	return(com_rd(arcn));
    403 }
    404 
    405 /*
    406  * cpio_endrd()
    407  *      no cleanup needed here, just return size of the trailer (for append)
    408  * Return:
    409  *      size of trailer header in this format
    410  */
    411 
    412 #if __STDC__
    413 off_t
    414 cpio_endrd(void)
    415 #else
    416 off_t
    417 cpio_endrd()
    418 #endif
    419 {
    420 	return((off_t)(sizeof(HD_CPIO) + sizeof(TRAILER)));
    421 }
    422 
    423 /*
    424  * cpio_stwr()
    425  *	start up the device mapping table
    426  * Return:
    427  *	0 if ok, -1 otherwise (what dev_start() returns)
    428  */
    429 
    430 #if __STDC__
    431 int
    432 cpio_stwr(void)
    433 #else
    434 int
    435 cpio_stwr()
    436 #endif
    437 {
    438 	return(dev_start());
    439 }
    440 
    441 /*
    442  * cpio_wr()
    443  *	copy the data in the ARCHD to buffer in extended byte oriented cpio
    444  *	format.
    445  * Return
    446  *      0 if file has data to be written after the header, 1 if file has NO
    447  *	data to write after the header, -1 if archive write failed
    448  */
    449 
    450 #if __STDC__
    451 int
    452 cpio_wr(ARCHD *arcn)
    453 #else
    454 int
    455 cpio_wr(arcn)
    456 	ARCHD *arcn;
    457 #endif
    458 {
    459 	HD_CPIO *hd;
    460 	int nsz;
    461 	char hdblk[sizeof(HD_CPIO)];
    462 
    463 	/*
    464 	 * check and repair truncated device and inode fields in the header
    465 	 */
    466 	if (map_dev(arcn, (u_long)CPIO_MASK, (u_long)CPIO_MASK) < 0)
    467 		return(-1);
    468 
    469 	arcn->pad = 0L;
    470 	nsz = arcn->nlen + 1;
    471 	hd = (HD_CPIO *)hdblk;
    472 	if ((arcn->type != PAX_BLK) && (arcn->type != PAX_CHR))
    473 		arcn->sb.st_rdev = 0;
    474 
    475 	switch(arcn->type) {
    476 	case PAX_CTG:
    477 	case PAX_REG:
    478 	case PAX_HRG:
    479 		/*
    480 		 * set data size for file data
    481 		 */
    482 #		ifdef NET2_STAT
    483 		if (ul_asc((u_long)arcn->sb.st_size, hd->c_filesize,
    484 		    sizeof(hd->c_filesize), OCT)) {
    485 #		else
    486 		if (uqd_asc((u_quad_t)arcn->sb.st_size, hd->c_filesize,
    487 		    sizeof(hd->c_filesize), OCT)) {
    488 #		endif
    489 			tty_warn(1,"File is too large for cpio format %s",
    490 			    arcn->org_name);
    491 			return(1);
    492 		}
    493 		break;
    494 	case PAX_SLK:
    495 		/*
    496 		 * set data size to hold link name
    497 		 */
    498 		if (ul_asc((u_long)arcn->ln_nlen, hd->c_filesize,
    499 		    sizeof(hd->c_filesize), OCT))
    500 			goto out;
    501 		break;
    502 	default:
    503 		/*
    504 		 * all other file types have no file data
    505 		 */
    506 		if (ul_asc((u_long)0, hd->c_filesize, sizeof(hd->c_filesize),
    507 		     OCT))
    508 			goto out;
    509 		break;
    510 	}
    511 
    512 	/*
    513 	 * copy the values to the header using octal ascii
    514 	 */
    515 	if (ul_asc((u_long)MAGIC, hd->c_magic, sizeof(hd->c_magic), OCT) ||
    516 	    ul_asc((u_long)arcn->sb.st_dev, hd->c_dev, sizeof(hd->c_dev),
    517 	        OCT) ||
    518 	    ul_asc((u_long)arcn->sb.st_ino, hd->c_ino, sizeof(hd->c_ino),
    519 		OCT) ||
    520 	    ul_asc((u_long)arcn->sb.st_mode, hd->c_mode, sizeof(hd->c_mode),
    521 		OCT) ||
    522 	    ul_asc((u_long)arcn->sb.st_uid, hd->c_uid, sizeof(hd->c_uid),
    523 		OCT) ||
    524 	    ul_asc((u_long)arcn->sb.st_gid, hd->c_gid, sizeof(hd->c_gid),
    525 		OCT) ||
    526 	    ul_asc((u_long)arcn->sb.st_nlink, hd->c_nlink, sizeof(hd->c_nlink),
    527 		 OCT) ||
    528 	    ul_asc((u_long)arcn->sb.st_rdev, hd->c_rdev, sizeof(hd->c_rdev),
    529 		OCT) ||
    530 	    ul_asc((u_long)arcn->sb.st_mtime,hd->c_mtime,sizeof(hd->c_mtime),
    531 		OCT) ||
    532 	    ul_asc((u_long)nsz, hd->c_namesize, sizeof(hd->c_namesize), OCT))
    533 		goto out;
    534 
    535 	/*
    536 	 * write the file name to the archive
    537 	 */
    538 	if ((wr_rdbuf(hdblk, (int)sizeof(HD_CPIO)) < 0) ||
    539 	    (wr_rdbuf(arcn->name, nsz) < 0)) {
    540 		tty_warn(1, "Unable to write cpio header for %s",
    541 		    arcn->org_name);
    542 		return(-1);
    543 	}
    544 
    545 	/*
    546 	 * if this file has data, we are done. The caller will write the file
    547 	 * data, if we are link tell caller we are done, go to next file
    548 	 */
    549 	if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG) ||
    550 	    (arcn->type == PAX_HRG))
    551 		return(0);
    552 	if (arcn->type != PAX_SLK)
    553 		return(1);
    554 
    555 	/*
    556 	 * write the link name to the archive, tell the caller to go to the
    557 	 * next file as we are done.
    558 	 */
    559 	if (wr_rdbuf(arcn->ln_name, arcn->ln_nlen) < 0) {
    560 		tty_warn(1,"Unable to write cpio link name for %s",
    561 		    arcn->org_name);
    562 		return(-1);
    563 	}
    564 	return(1);
    565 
    566     out:
    567 	/*
    568 	 * header field is out of range
    569 	 */
    570 	tty_warn(1, "Cpio header field is too small to store file %s",
    571 	    arcn->org_name);
    572 	return(1);
    573 }
    574 
    575 /*
    576  * Routines common to the system VR4 version of cpio (with/without file CRC)
    577  */
    578 
    579 /*
    580  * vcpio_id()
    581  *      determine if a block given to us is a valid system VR4 cpio header
    582  *	WITHOUT crc. WATCH it the magic cookies are in OCTAL, the header
    583  *	uses HEX
    584  * Return:
    585  *      0 if a valid header, -1 otherwise
    586  */
    587 
    588 #if __STDC__
    589 int
    590 vcpio_id(char *blk, int size)
    591 #else
    592 int
    593 vcpio_id(blk, size)
    594 	char *blk;
    595 	int size;
    596 #endif
    597 {
    598 	if ((size < sizeof(HD_VCPIO)) ||
    599 	    (strncmp(blk, AVMAGIC, sizeof(AVMAGIC) - 1) != 0))
    600 		return(-1);
    601 	return(0);
    602 }
    603 
    604 /*
    605  * crc_id()
    606  *      determine if a block given to us is a valid system VR4 cpio header
    607  *	WITH crc. WATCH it the magic cookies are in OCTAL the header uses HEX
    608  * Return:
    609  *      0 if a valid header, -1 otherwise
    610  */
    611 
    612 #if __STDC__
    613 int
    614 crc_id(char *blk, int size)
    615 #else
    616 int
    617 crc_id(blk, size)
    618 	char *blk;
    619 	int size;
    620 #endif
    621 {
    622 	if ((size < sizeof(HD_VCPIO)) ||
    623 	    (strncmp(blk, AVCMAGIC, sizeof(AVCMAGIC) - 1) != 0))
    624 		return(-1);
    625 	return(0);
    626 }
    627 
    628 /*
    629  * crc_strd()
    630  w	set file data CRC calculations. Fire up the hard link detection code
    631  * Return:
    632  *      0 if ok -1 otherwise (the return values of lnk_start())
    633  */
    634 
    635 #if __STDC__
    636 int
    637 crc_strd(void)
    638 #else
    639 int
    640 crc_strd()
    641 #endif
    642 {
    643 	docrc = 1;
    644 	return(lnk_start());
    645 }
    646 
    647 /*
    648  * vcpio_rd()
    649  *	determine if a buffer is a system VR4 archive entry. (with/without CRC)
    650  *	convert and store the values in the ARCHD parameter.
    651  * Return:
    652  *	0 if a valid header, -1 otherwise.
    653  */
    654 
    655 #if __STDC__
    656 int
    657 vcpio_rd(ARCHD *arcn, char *buf)
    658 #else
    659 int
    660 vcpio_rd(arcn, buf)
    661 	ARCHD *arcn;
    662 	char *buf;
    663 #endif
    664 {
    665 	HD_VCPIO *hd;
    666 	dev_t devminor;
    667 	dev_t devmajor;
    668 	int nsz;
    669 
    670 	/*
    671 	 * during the id phase it was determined if we were using CRC, use the
    672 	 * proper id routine.
    673 	 */
    674 	if (docrc) {
    675 		if (crc_id(buf, sizeof(HD_VCPIO)) < 0)
    676 			return(-1);
    677 	} else {
    678 		if (vcpio_id(buf, sizeof(HD_VCPIO)) < 0)
    679 			return(-1);
    680 	}
    681 
    682 	hd = (HD_VCPIO *)buf;
    683 	arcn->pad = 0L;
    684 
    685 	/*
    686 	 * extract the hex ascii fields from the header
    687 	 */
    688 	arcn->sb.st_ino = (ino_t)asc_ul(hd->c_ino, sizeof(hd->c_ino), HEX);
    689 	arcn->sb.st_mode = (mode_t)asc_ul(hd->c_mode, sizeof(hd->c_mode), HEX);
    690 	arcn->sb.st_uid = (uid_t)asc_ul(hd->c_uid, sizeof(hd->c_uid), HEX);
    691 	arcn->sb.st_gid = (gid_t)asc_ul(hd->c_gid, sizeof(hd->c_gid), HEX);
    692 	arcn->sb.st_mtime = (time_t)asc_ul(hd->c_mtime,sizeof(hd->c_mtime),HEX);
    693 	arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime;
    694 #	ifdef NET2_STAT
    695 	arcn->sb.st_size = (off_t)asc_ul(hd->c_filesize,
    696 	    sizeof(hd->c_filesize), HEX);
    697 #	else
    698 	arcn->sb.st_size = (off_t)asc_uqd(hd->c_filesize,
    699 	    sizeof(hd->c_filesize), HEX);
    700 #	endif
    701 	arcn->sb.st_nlink = (nlink_t)asc_ul(hd->c_nlink, sizeof(hd->c_nlink),
    702 	    HEX);
    703 	devmajor = (dev_t)asc_ul(hd->c_maj, sizeof(hd->c_maj), HEX);
    704 	devminor = (dev_t)asc_ul(hd->c_min, sizeof(hd->c_min), HEX);
    705 	arcn->sb.st_dev = TODEV(devmajor, devminor);
    706 	devmajor = (dev_t)asc_ul(hd->c_rmaj, sizeof(hd->c_maj), HEX);
    707 	devminor = (dev_t)asc_ul(hd->c_rmin, sizeof(hd->c_min), HEX);
    708 	arcn->sb.st_rdev = TODEV(devmajor, devminor);
    709 	arcn->crc = asc_ul(hd->c_chksum, sizeof(hd->c_chksum), HEX);
    710 
    711 	/*
    712 	 * check the length of the file name, if ok read it in, return -1 if
    713 	 * bogus
    714 	 */
    715 	if ((nsz = (int)asc_ul(hd->c_namesize,sizeof(hd->c_namesize),HEX)) < 2)
    716 		return(-1);
    717 	arcn->nlen = nsz - 1;
    718 	if (rd_nm(arcn, nsz) < 0)
    719 		return(-1);
    720 
    721 	/*
    722 	 * skip padding. header + filename is aligned to 4 byte boundries
    723 	 */
    724 	if (rd_skip((off_t)(VCPIO_PAD(sizeof(HD_VCPIO) + nsz))) < 0)
    725 		return(-1);
    726 
    727 	/*
    728 	 * if not a link (or a file with no data), calculate pad size (for
    729 	 * padding which follows the file data), clear the link name and return
    730 	 */
    731 	if (((arcn->sb.st_mode&C_IFMT) != C_ISLNK)||(arcn->sb.st_size == 0)) {
    732 		/*
    733 		 * we have a valid header (not a link)
    734 		 */
    735 		arcn->ln_nlen = 0;
    736 		arcn->ln_name[0] = '\0';
    737 		arcn->pad = VCPIO_PAD(arcn->sb.st_size);
    738 		return(com_rd(arcn));
    739 	}
    740 
    741 	/*
    742 	 * read in the link name and skip over the padding
    743 	 */
    744 	if ((rd_ln_nm(arcn) < 0) ||
    745 	    (rd_skip((off_t)(VCPIO_PAD(arcn->sb.st_size))) < 0))
    746 		return(-1);
    747 
    748 	/*
    749 	 * we have a valid header (with a link)
    750 	 */
    751 	return(com_rd(arcn));
    752 }
    753 
    754 /*
    755  * vcpio_endrd()
    756  *      no cleanup needed here, just return size of the trailer (for append)
    757  * Return:
    758  *      size of trailer header in this format
    759  */
    760 
    761 #if __STDC__
    762 off_t
    763 vcpio_endrd(void)
    764 #else
    765 off_t
    766 vcpio_endrd()
    767 #endif
    768 {
    769 	return((off_t)(sizeof(HD_VCPIO) + sizeof(TRAILER) +
    770 		(VCPIO_PAD(sizeof(HD_VCPIO) + sizeof(TRAILER)))));
    771 }
    772 
    773 /*
    774  * crc_stwr()
    775  *	start up the device mapping table, enable crc file calculation
    776  * Return:
    777  *	0 if ok, -1 otherwise (what dev_start() returns)
    778  */
    779 
    780 #if __STDC__
    781 int
    782 crc_stwr(void)
    783 #else
    784 int
    785 crc_stwr()
    786 #endif
    787 {
    788 	docrc = 1;
    789 	return(dev_start());
    790 }
    791 
    792 /*
    793  * vcpio_wr()
    794  *	copy the data in the ARCHD to buffer in system VR4 cpio
    795  *	(with/without crc) format.
    796  * Return
    797  *	0 if file has data to be written after the header, 1 if file has
    798  *	NO data to write after the header, -1 if archive write failed
    799  */
    800 
    801 #if __STDC__
    802 int
    803 vcpio_wr(ARCHD *arcn)
    804 #else
    805 int
    806 vcpio_wr(arcn)
    807 	ARCHD *arcn;
    808 #endif
    809 {
    810 	HD_VCPIO *hd;
    811 	unsigned int nsz;
    812 	char hdblk[sizeof(HD_VCPIO)];
    813 
    814 	/*
    815 	 * check and repair truncated device and inode fields in the cpio
    816 	 * header
    817 	 */
    818 	if (map_dev(arcn, (u_long)VCPIO_MASK, (u_long)VCPIO_MASK) < 0)
    819 		return(-1);
    820 	nsz = arcn->nlen + 1;
    821 	hd = (HD_VCPIO *)hdblk;
    822 	if ((arcn->type != PAX_BLK) && (arcn->type != PAX_CHR))
    823 		arcn->sb.st_rdev = 0;
    824 
    825 	/*
    826 	 * add the proper magic value depending whether we were asked for
    827 	 * file data crc's, and the crc if needed.
    828 	 */
    829 	if (docrc) {
    830 		if (ul_asc((u_long)VCMAGIC, hd->c_magic, sizeof(hd->c_magic),
    831 	    		OCT) ||
    832 		    ul_asc((u_long)arcn->crc,hd->c_chksum,sizeof(hd->c_chksum),
    833 	    		HEX))
    834 			goto out;
    835 	} else {
    836 		if (ul_asc((u_long)VMAGIC, hd->c_magic, sizeof(hd->c_magic),
    837 	    		OCT) ||
    838 		    ul_asc((u_long)0L, hd->c_chksum, sizeof(hd->c_chksum),HEX))
    839 			goto out;
    840 	}
    841 
    842 	switch(arcn->type) {
    843 	case PAX_CTG:
    844 	case PAX_REG:
    845 	case PAX_HRG:
    846 		/*
    847 		 * caller will copy file data to the archive. tell him how
    848 		 * much to pad.
    849 		 */
    850 		arcn->pad = VCPIO_PAD(arcn->sb.st_size);
    851 #		ifdef NET2_STAT
    852 		if (ul_asc((u_long)arcn->sb.st_size, hd->c_filesize,
    853 		    sizeof(hd->c_filesize), HEX)) {
    854 #		else
    855 		if (uqd_asc((u_quad_t)arcn->sb.st_size, hd->c_filesize,
    856 		    sizeof(hd->c_filesize), HEX)) {
    857 #		endif
    858 			tty_warn(1,"File is too large for sv4cpio format %s",
    859 			    arcn->org_name);
    860 			return(1);
    861 		}
    862 		break;
    863 	case PAX_SLK:
    864 		/*
    865 		 * no file data for the caller to process, the file data has
    866 		 * the size of the link
    867 		 */
    868 		arcn->pad = 0L;
    869 		if (ul_asc((u_long)arcn->ln_nlen, hd->c_filesize,
    870 		    sizeof(hd->c_filesize), HEX))
    871 			goto out;
    872 		break;
    873 	default:
    874 		/*
    875 		 * no file data for the caller to process
    876 		 */
    877 		arcn->pad = 0L;
    878 		if (ul_asc((u_long)0L, hd->c_filesize, sizeof(hd->c_filesize),
    879 		    HEX))
    880 			goto out;
    881 		break;
    882 	}
    883 
    884 	/*
    885 	 * set the other fields in the header
    886 	 */
    887 	if (ul_asc((u_long)arcn->sb.st_ino, hd->c_ino, sizeof(hd->c_ino),
    888 		HEX) ||
    889 	    ul_asc((u_long)arcn->sb.st_mode, hd->c_mode, sizeof(hd->c_mode),
    890 		HEX) ||
    891 	    ul_asc((u_long)arcn->sb.st_uid, hd->c_uid, sizeof(hd->c_uid),
    892 		HEX) ||
    893 	    ul_asc((u_long)arcn->sb.st_gid, hd->c_gid, sizeof(hd->c_gid),
    894     		HEX) ||
    895 	    ul_asc((u_long)arcn->sb.st_mtime, hd->c_mtime, sizeof(hd->c_mtime),
    896     		HEX) ||
    897 	    ul_asc((u_long)arcn->sb.st_nlink, hd->c_nlink, sizeof(hd->c_nlink),
    898     		HEX) ||
    899 	    ul_asc((u_long)MAJOR(arcn->sb.st_dev),hd->c_maj, sizeof(hd->c_maj),
    900 		HEX) ||
    901 	    ul_asc((u_long)MINOR(arcn->sb.st_dev),hd->c_min, sizeof(hd->c_min),
    902 		HEX) ||
    903 	    ul_asc((u_long)MAJOR(arcn->sb.st_rdev),hd->c_rmaj,sizeof(hd->c_maj),
    904 		HEX) ||
    905 	    ul_asc((u_long)MINOR(arcn->sb.st_rdev),hd->c_rmin,sizeof(hd->c_min),
    906 		HEX) ||
    907 	    ul_asc((u_long)nsz, hd->c_namesize, sizeof(hd->c_namesize), HEX))
    908 		goto out;
    909 
    910 	/*
    911 	 * write the header, the file name and padding as required.
    912 	 */
    913 	if ((wr_rdbuf(hdblk, (int)sizeof(HD_VCPIO)) < 0) ||
    914 	    (wr_rdbuf(arcn->name, (int)nsz) < 0)  ||
    915 	    (wr_skip((off_t)(VCPIO_PAD(sizeof(HD_VCPIO) + nsz))) < 0)) {
    916 		tty_warn(1,"Could not write sv4cpio header for %s",
    917 		    arcn->org_name);
    918 		return(-1);
    919 	}
    920 
    921 	/*
    922 	 * if we have file data, tell the caller we are done, copy the file
    923 	 */
    924 	if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG) ||
    925 	    (arcn->type == PAX_HRG))
    926 		return(0);
    927 
    928 	/*
    929 	 * if we are not a link, tell the caller we are done, go to next file
    930 	 */
    931 	if (arcn->type != PAX_SLK)
    932 		return(1);
    933 
    934 	/*
    935 	 * write the link name, tell the caller we are done.
    936 	 */
    937 	if ((wr_rdbuf(arcn->ln_name, arcn->ln_nlen) < 0) ||
    938 	    (wr_skip((off_t)(VCPIO_PAD(arcn->ln_nlen))) < 0)) {
    939 		tty_warn(1,"Could not write sv4cpio link name for %s",
    940 		    arcn->org_name);
    941 		return(-1);
    942 	}
    943 	return(1);
    944 
    945     out:
    946 	/*
    947 	 * header field is out of range
    948 	 */
    949 	tty_warn(1,"Sv4cpio header field is too small for file %s",
    950 	    arcn->org_name);
    951 	return(1);
    952 }
    953 
    954 /*
    955  * Routines common to the old binary header cpio
    956  */
    957 
    958 /*
    959  * bcpio_id()
    960  *      determine if a block given to us is a old binary cpio header
    961  *	(with/without header byte swapping)
    962  * Return:
    963  *      0 if a valid header, -1 otherwise
    964  */
    965 
    966 #if __STDC__
    967 int
    968 bcpio_id(char *blk, int size)
    969 #else
    970 int
    971 bcpio_id(blk, size)
    972 	char *blk;
    973 	int size;
    974 #endif
    975 {
    976 	if (size < sizeof(HD_BCPIO))
    977 		return(-1);
    978 
    979 	/*
    980 	 * check both normal and byte swapped magic cookies
    981 	 */
    982 	if (((u_short)SHRT_EXT(blk)) == MAGIC)
    983 		return(0);
    984 	if (((u_short)RSHRT_EXT(blk)) == MAGIC) {
    985 		if (!swp_head)
    986 			++swp_head;
    987 		return(0);
    988 	}
    989 	return(-1);
    990 }
    991 
    992 /*
    993  * bcpio_rd()
    994  *	determine if a buffer is a old binary archive entry. (it may have byte
    995  *	swapped header) convert and store the values in the ARCHD parameter.
    996  *	This is a very old header format and should not really be used.
    997  * Return:
    998  *	0 if a valid header, -1 otherwise.
    999  */
   1000 
   1001 #if __STDC__
   1002 int
   1003 bcpio_rd(ARCHD *arcn, char *buf)
   1004 #else
   1005 int
   1006 bcpio_rd(arcn, buf)
   1007 	ARCHD *arcn;
   1008 	char *buf;
   1009 #endif
   1010 {
   1011 	HD_BCPIO *hd;
   1012 	int nsz;
   1013 
   1014 	/*
   1015 	 * check the header
   1016 	 */
   1017 	if (bcpio_id(buf, sizeof(HD_BCPIO)) < 0)
   1018 		return(-1);
   1019 
   1020 	arcn->pad = 0L;
   1021 	hd = (HD_BCPIO *)buf;
   1022 	if (swp_head) {
   1023 		/*
   1024 		 * header has swapped bytes on 16 bit boundries
   1025 		 */
   1026 		arcn->sb.st_dev = (dev_t)(RSHRT_EXT(hd->h_dev));
   1027 		arcn->sb.st_ino = (ino_t)(RSHRT_EXT(hd->h_ino));
   1028 		arcn->sb.st_mode = (mode_t)(RSHRT_EXT(hd->h_mode));
   1029 		arcn->sb.st_uid = (uid_t)(RSHRT_EXT(hd->h_uid));
   1030 		arcn->sb.st_gid = (gid_t)(RSHRT_EXT(hd->h_gid));
   1031 		arcn->sb.st_nlink = (nlink_t)(RSHRT_EXT(hd->h_nlink));
   1032 		arcn->sb.st_rdev = (dev_t)(RSHRT_EXT(hd->h_rdev));
   1033 		arcn->sb.st_mtime = (time_t)(RSHRT_EXT(hd->h_mtime_1));
   1034 		arcn->sb.st_mtime =  (arcn->sb.st_mtime << 16) |
   1035 			((time_t)(RSHRT_EXT(hd->h_mtime_2)));
   1036 		arcn->sb.st_size = (off_t)(RSHRT_EXT(hd->h_filesize_1));
   1037 		arcn->sb.st_size = (arcn->sb.st_size << 16) |
   1038 			((off_t)(RSHRT_EXT(hd->h_filesize_2)));
   1039 		nsz = (int)(RSHRT_EXT(hd->h_namesize));
   1040 	} else {
   1041 		arcn->sb.st_dev = (dev_t)(SHRT_EXT(hd->h_dev));
   1042 		arcn->sb.st_ino = (ino_t)(SHRT_EXT(hd->h_ino));
   1043 		arcn->sb.st_mode = (mode_t)(SHRT_EXT(hd->h_mode));
   1044 		arcn->sb.st_uid = (uid_t)(SHRT_EXT(hd->h_uid));
   1045 		arcn->sb.st_gid = (gid_t)(SHRT_EXT(hd->h_gid));
   1046 		arcn->sb.st_nlink = (nlink_t)(SHRT_EXT(hd->h_nlink));
   1047 		arcn->sb.st_rdev = (dev_t)(SHRT_EXT(hd->h_rdev));
   1048 		arcn->sb.st_mtime = (time_t)(SHRT_EXT(hd->h_mtime_1));
   1049 		arcn->sb.st_mtime =  (arcn->sb.st_mtime << 16) |
   1050 			((time_t)(SHRT_EXT(hd->h_mtime_2)));
   1051 		arcn->sb.st_size = (off_t)(SHRT_EXT(hd->h_filesize_1));
   1052 		arcn->sb.st_size = (arcn->sb.st_size << 16) |
   1053 			((off_t)(SHRT_EXT(hd->h_filesize_2)));
   1054 		nsz = (int)(SHRT_EXT(hd->h_namesize));
   1055 	}
   1056 	arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime;
   1057 
   1058 	/*
   1059 	 * check the file name size, if bogus give up. otherwise read the file
   1060 	 * name
   1061 	 */
   1062 	if (nsz < 2)
   1063 		return(-1);
   1064 	arcn->nlen = nsz - 1;
   1065 	if (rd_nm(arcn, nsz) < 0)
   1066 		return(-1);
   1067 
   1068 	/*
   1069 	 * header + file name are aligned to 2 byte boundries, skip if needed
   1070 	 */
   1071 	if (rd_skip((off_t)(BCPIO_PAD(sizeof(HD_BCPIO) + nsz))) < 0)
   1072 		return(-1);
   1073 
   1074 	/*
   1075 	 * if not a link (or a file with no data), calculate pad size (for
   1076 	 * padding which follows the file data), clear the link name and return
   1077 	 */
   1078 	if (((arcn->sb.st_mode & C_IFMT) != C_ISLNK)||(arcn->sb.st_size == 0)){
   1079 		/*
   1080 		 * we have a valid header (not a link)
   1081 		 */
   1082 		arcn->ln_nlen = 0;
   1083 		arcn->ln_name[0] = '\0';
   1084 		arcn->pad = BCPIO_PAD(arcn->sb.st_size);
   1085 		return(com_rd(arcn));
   1086 	}
   1087 
   1088 	if ((rd_ln_nm(arcn) < 0) ||
   1089 	    (rd_skip((off_t)(BCPIO_PAD(arcn->sb.st_size))) < 0))
   1090 		return(-1);
   1091 
   1092 	/*
   1093 	 * we have a valid header (with a link)
   1094 	 */
   1095 	return(com_rd(arcn));
   1096 }
   1097 
   1098 /*
   1099  * bcpio_endrd()
   1100  *      no cleanup needed here, just return size of the trailer (for append)
   1101  * Return:
   1102  *      size of trailer header in this format
   1103  */
   1104 
   1105 #if __STDC__
   1106 off_t
   1107 bcpio_endrd(void)
   1108 #else
   1109 off_t
   1110 bcpio_endrd()
   1111 #endif
   1112 {
   1113 	return((off_t)(sizeof(HD_BCPIO) + sizeof(TRAILER) +
   1114 		(BCPIO_PAD(sizeof(HD_BCPIO) + sizeof(TRAILER)))));
   1115 }
   1116 
   1117 /*
   1118  * bcpio_wr()
   1119  *	copy the data in the ARCHD to buffer in old binary cpio format
   1120  *	There is a real chance of field overflow with this critter. So we
   1121  *	always check the conversion is ok. nobody in his their right mind
   1122  *	should write an achive in this format...
   1123  * Return
   1124  *      0 if file has data to be written after the header, 1 if file has NO
   1125  *	data to write after the header, -1 if archive write failed
   1126  */
   1127 
   1128 #if __STDC__
   1129 int
   1130 bcpio_wr(ARCHD *arcn)
   1131 #else
   1132 int
   1133 bcpio_wr(arcn)
   1134 	ARCHD *arcn;
   1135 #endif
   1136 {
   1137 	HD_BCPIO *hd;
   1138 	int nsz;
   1139 	char hdblk[sizeof(HD_BCPIO)];
   1140 	off_t t_offt;
   1141 	int t_int;
   1142 	time_t t_timet;
   1143 
   1144 	/*
   1145 	 * check and repair truncated device and inode fields in the cpio
   1146 	 * header
   1147 	 */
   1148 	if (map_dev(arcn, (u_long)BCPIO_MASK, (u_long)BCPIO_MASK) < 0)
   1149 		return(-1);
   1150 
   1151 	if ((arcn->type != PAX_BLK) && (arcn->type != PAX_CHR))
   1152 		arcn->sb.st_rdev = 0;
   1153 	hd = (HD_BCPIO *)hdblk;
   1154 
   1155 	switch(arcn->type) {
   1156 	case PAX_CTG:
   1157 	case PAX_REG:
   1158 	case PAX_HRG:
   1159 		/*
   1160 		 * caller will copy file data to the archive. tell him how
   1161 		 * much to pad.
   1162 		 */
   1163 		arcn->pad = BCPIO_PAD(arcn->sb.st_size);
   1164 		hd->h_filesize_1[0] = CHR_WR_0(arcn->sb.st_size);
   1165 		hd->h_filesize_1[1] = CHR_WR_1(arcn->sb.st_size);
   1166 		hd->h_filesize_2[0] = CHR_WR_2(arcn->sb.st_size);
   1167 		hd->h_filesize_2[1] = CHR_WR_3(arcn->sb.st_size);
   1168 		t_offt = (off_t)(SHRT_EXT(hd->h_filesize_1));
   1169 		t_offt = (t_offt<<16) | ((off_t)(SHRT_EXT(hd->h_filesize_2)));
   1170 		if (arcn->sb.st_size != t_offt) {
   1171 			tty_warn(1,"File is too large for bcpio format %s",
   1172 			    arcn->org_name);
   1173 			return(1);
   1174 		}
   1175 		break;
   1176 	case PAX_SLK:
   1177 		/*
   1178 		 * no file data for the caller to process, the file data has
   1179 		 * the size of the link
   1180 		 */
   1181 		arcn->pad = 0L;
   1182 		hd->h_filesize_1[0] = CHR_WR_0(arcn->ln_nlen);
   1183 		hd->h_filesize_1[1] = CHR_WR_1(arcn->ln_nlen);
   1184 		hd->h_filesize_2[0] = CHR_WR_2(arcn->ln_nlen);
   1185 		hd->h_filesize_2[1] = CHR_WR_3(arcn->ln_nlen);
   1186 		t_int = (int)(SHRT_EXT(hd->h_filesize_1));
   1187 		t_int = (t_int << 16) | ((int)(SHRT_EXT(hd->h_filesize_2)));
   1188 		if (arcn->ln_nlen != t_int)
   1189 			goto out;
   1190 		break;
   1191 	default:
   1192 		/*
   1193 		 * no file data for the caller to process
   1194 		 */
   1195 		arcn->pad = 0L;
   1196 		hd->h_filesize_1[0] = (char)0;
   1197 		hd->h_filesize_1[1] = (char)0;
   1198 		hd->h_filesize_2[0] = (char)0;
   1199 		hd->h_filesize_2[1] = (char)0;
   1200 		break;
   1201 	}
   1202 
   1203 	/*
   1204 	 * build up the rest of the fields
   1205 	 */
   1206 	hd->h_magic[0] = CHR_WR_2(MAGIC);
   1207 	hd->h_magic[1] = CHR_WR_3(MAGIC);
   1208 	hd->h_dev[0] = CHR_WR_2(arcn->sb.st_dev);
   1209 	hd->h_dev[1] = CHR_WR_3(arcn->sb.st_dev);
   1210 	if (arcn->sb.st_dev != (dev_t)(SHRT_EXT(hd->h_dev)))
   1211 		goto out;
   1212 	hd->h_ino[0] = CHR_WR_2(arcn->sb.st_ino);
   1213 	hd->h_ino[1] = CHR_WR_3(arcn->sb.st_ino);
   1214 	if (arcn->sb.st_ino != (ino_t)(SHRT_EXT(hd->h_ino)))
   1215 		goto out;
   1216 	hd->h_mode[0] = CHR_WR_2(arcn->sb.st_mode);
   1217 	hd->h_mode[1] = CHR_WR_3(arcn->sb.st_mode);
   1218 	if (arcn->sb.st_mode != (mode_t)(SHRT_EXT(hd->h_mode)))
   1219 		goto out;
   1220 	hd->h_uid[0] = CHR_WR_2(arcn->sb.st_uid);
   1221 	hd->h_uid[1] = CHR_WR_3(arcn->sb.st_uid);
   1222 	if (arcn->sb.st_uid != (uid_t)(SHRT_EXT(hd->h_uid)))
   1223 		goto out;
   1224 	hd->h_gid[0] = CHR_WR_2(arcn->sb.st_gid);
   1225 	hd->h_gid[1] = CHR_WR_3(arcn->sb.st_gid);
   1226 	if (arcn->sb.st_gid != (gid_t)(SHRT_EXT(hd->h_gid)))
   1227 		goto out;
   1228 	hd->h_nlink[0] = CHR_WR_2(arcn->sb.st_nlink);
   1229 	hd->h_nlink[1] = CHR_WR_3(arcn->sb.st_nlink);
   1230 	if (arcn->sb.st_nlink != (nlink_t)(SHRT_EXT(hd->h_nlink)))
   1231 		goto out;
   1232 	hd->h_rdev[0] = CHR_WR_2(arcn->sb.st_rdev);
   1233 	hd->h_rdev[1] = CHR_WR_3(arcn->sb.st_rdev);
   1234 	if (arcn->sb.st_rdev != (dev_t)(SHRT_EXT(hd->h_rdev)))
   1235 		goto out;
   1236 	hd->h_mtime_1[0] = CHR_WR_0(arcn->sb.st_mtime);
   1237 	hd->h_mtime_1[1] = CHR_WR_1(arcn->sb.st_mtime);
   1238 	hd->h_mtime_2[0] = CHR_WR_2(arcn->sb.st_mtime);
   1239 	hd->h_mtime_2[1] = CHR_WR_3(arcn->sb.st_mtime);
   1240 	t_timet = (time_t)(SHRT_EXT(hd->h_mtime_1));
   1241 	t_timet =  (t_timet << 16) | ((time_t)(SHRT_EXT(hd->h_mtime_2)));
   1242 	if (arcn->sb.st_mtime != t_timet)
   1243 		goto out;
   1244 	nsz = arcn->nlen + 1;
   1245 	hd->h_namesize[0] = CHR_WR_2(nsz);
   1246 	hd->h_namesize[1] = CHR_WR_3(nsz);
   1247 	if (nsz != (int)(SHRT_EXT(hd->h_namesize)))
   1248 		goto out;
   1249 
   1250 	/*
   1251 	 * write the header, the file name and padding as required.
   1252 	 */
   1253 	if ((wr_rdbuf(hdblk, (int)sizeof(HD_BCPIO)) < 0) ||
   1254 	    (wr_rdbuf(arcn->name, nsz) < 0) ||
   1255 	    (wr_skip((off_t)(BCPIO_PAD(sizeof(HD_BCPIO) + nsz))) < 0)) {
   1256 		tty_warn(1, "Could not write bcpio header for %s",
   1257 		    arcn->org_name);
   1258 		return(-1);
   1259 	}
   1260 
   1261 	/*
   1262 	 * if we have file data, tell the caller we are done
   1263 	 */
   1264 	if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG) ||
   1265 	    (arcn->type == PAX_HRG))
   1266 		return(0);
   1267 
   1268 	/*
   1269 	 * if we are not a link, tell the caller we are done, go to next file
   1270 	 */
   1271 	if (arcn->type != PAX_SLK)
   1272 		return(1);
   1273 
   1274 	/*
   1275 	 * write the link name, tell the caller we are done.
   1276 	 */
   1277 	if ((wr_rdbuf(arcn->ln_name, arcn->ln_nlen) < 0) ||
   1278 	    (wr_skip((off_t)(BCPIO_PAD(arcn->ln_nlen))) < 0)) {
   1279 		tty_warn(1,"Could not write bcpio link name for %s",
   1280 		    arcn->org_name);
   1281 		return(-1);
   1282 	}
   1283 	return(1);
   1284 
   1285     out:
   1286 	/*
   1287 	 * header field is out of range
   1288 	 */
   1289 	tty_warn(1,"Bcpio header field is too small for file %s",
   1290 	    arcn->org_name);
   1291 	return(1);
   1292 }
   1293