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