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