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