xref: /freebsd/bin/pax/cpio.c (revision 778766fe4d194c8ea0e580bc2906a93e7318faf8)
14b88c807SRodney W. Grimes /*-
24b88c807SRodney W. Grimes  * Copyright (c) 1992 Keith Muller.
34b88c807SRodney W. Grimes  * Copyright (c) 1992, 1993
44b88c807SRodney W. Grimes  *	The Regents of the University of California.  All rights reserved.
54b88c807SRodney W. Grimes  *
64b88c807SRodney W. Grimes  * This code is derived from software contributed to Berkeley by
74b88c807SRodney W. Grimes  * Keith Muller of the University of California, San Diego.
84b88c807SRodney W. Grimes  *
94b88c807SRodney W. Grimes  * Redistribution and use in source and binary forms, with or without
104b88c807SRodney W. Grimes  * modification, are permitted provided that the following conditions
114b88c807SRodney W. Grimes  * are met:
124b88c807SRodney W. Grimes  * 1. Redistributions of source code must retain the above copyright
134b88c807SRodney W. Grimes  *    notice, this list of conditions and the following disclaimer.
144b88c807SRodney W. Grimes  * 2. Redistributions in binary form must reproduce the above copyright
154b88c807SRodney W. Grimes  *    notice, this list of conditions and the following disclaimer in the
164b88c807SRodney W. Grimes  *    documentation and/or other materials provided with the distribution.
174b88c807SRodney W. Grimes  * 3. All advertising materials mentioning features or use of this software
184b88c807SRodney W. Grimes  *    must display the following acknowledgement:
194b88c807SRodney W. Grimes  *	This product includes software developed by the University of
204b88c807SRodney W. Grimes  *	California, Berkeley and its contributors.
214b88c807SRodney W. Grimes  * 4. Neither the name of the University nor the names of its contributors
224b88c807SRodney W. Grimes  *    may be used to endorse or promote products derived from this software
234b88c807SRodney W. Grimes  *    without specific prior written permission.
244b88c807SRodney W. Grimes  *
254b88c807SRodney W. Grimes  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
264b88c807SRodney W. Grimes  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
274b88c807SRodney W. Grimes  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
284b88c807SRodney W. Grimes  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
294b88c807SRodney W. Grimes  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
304b88c807SRodney W. Grimes  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
314b88c807SRodney W. Grimes  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
324b88c807SRodney W. Grimes  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
334b88c807SRodney W. Grimes  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
344b88c807SRodney W. Grimes  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
354b88c807SRodney W. Grimes  * SUCH DAMAGE.
364b88c807SRodney W. Grimes  */
374b88c807SRodney W. Grimes 
384b88c807SRodney W. Grimes #ifndef lint
39c9a8d1f4SPhilippe Charnier #if 0
40c9a8d1f4SPhilippe Charnier static char sccsid[] = "@(#)cpio.c	8.1 (Berkeley) 5/31/93";
41c9a8d1f4SPhilippe Charnier #endif
42c9a8d1f4SPhilippe Charnier static const char rcsid[] =
432a456239SPeter Wemm   "$FreeBSD$";
444b88c807SRodney W. Grimes #endif /* not lint */
454b88c807SRodney W. Grimes 
464b88c807SRodney W. Grimes #include <sys/types.h>
474b88c807SRodney W. Grimes #include <sys/time.h>
484b88c807SRodney W. Grimes #include <sys/stat.h>
494b88c807SRodney W. Grimes #include <string.h>
504b88c807SRodney W. Grimes #include <stdio.h>
514b88c807SRodney W. Grimes #include <unistd.h>
524b88c807SRodney W. Grimes #include <stdlib.h>
534b88c807SRodney W. Grimes #include "pax.h"
544b88c807SRodney W. Grimes #include "cpio.h"
554b88c807SRodney W. Grimes #include "extern.h"
564b88c807SRodney W. Grimes 
574b88c807SRodney W. Grimes static int rd_nm __P((register ARCHD *, int));
584b88c807SRodney W. Grimes static int rd_ln_nm __P((register ARCHD *));
594b88c807SRodney W. Grimes static int com_rd __P((register ARCHD *));
604b88c807SRodney W. Grimes 
614b88c807SRodney W. Grimes /*
624b88c807SRodney W. Grimes  * Routines which support the different cpio versions
634b88c807SRodney W. Grimes  */
644b88c807SRodney W. Grimes 
654b88c807SRodney W. Grimes static int swp_head;		/* binary cpio header byte swap */
664b88c807SRodney W. Grimes 
674b88c807SRodney W. Grimes /*
684b88c807SRodney W. Grimes  * Routines common to all versions of cpio
694b88c807SRodney W. Grimes  */
704b88c807SRodney W. Grimes 
714b88c807SRodney W. Grimes /*
724b88c807SRodney W. Grimes  * cpio_strd()
734b88c807SRodney W. Grimes  *	Fire up the hard link detection code
744b88c807SRodney W. Grimes  * Return:
754b88c807SRodney W. Grimes  *      0 if ok -1 otherwise (the return values of lnk_start())
764b88c807SRodney W. Grimes  */
774b88c807SRodney W. Grimes 
78778766feSKris Kennaway #ifdef __STDC__
794b88c807SRodney W. Grimes int
804b88c807SRodney W. Grimes cpio_strd(void)
814b88c807SRodney W. Grimes #else
824b88c807SRodney W. Grimes int
834b88c807SRodney W. Grimes cpio_strd()
844b88c807SRodney W. Grimes #endif
854b88c807SRodney W. Grimes {
864b88c807SRodney W. Grimes 	return(lnk_start());
874b88c807SRodney W. Grimes }
884b88c807SRodney W. Grimes 
894b88c807SRodney W. Grimes /*
904b88c807SRodney W. Grimes  * cpio_trail()
914b88c807SRodney W. Grimes  *	Called to determine if a header block is a valid trailer. We are
924b88c807SRodney W. Grimes  *	passed the block, the in_sync flag (which tells us we are in resync
934b88c807SRodney W. Grimes  *	mode; looking for a valid header), and cnt (which starts at zero)
944b88c807SRodney W. Grimes  *	which is used to count the number of empty blocks we have seen so far.
954b88c807SRodney W. Grimes  * Return:
964b88c807SRodney W. Grimes  *	0 if a valid trailer, -1 if not a valid trailer,
974b88c807SRodney W. Grimes  */
984b88c807SRodney W. Grimes 
99778766feSKris Kennaway #ifdef __STDC__
1004b88c807SRodney W. Grimes int
1014b88c807SRodney W. Grimes cpio_trail(register ARCHD *arcn)
1024b88c807SRodney W. Grimes #else
1034b88c807SRodney W. Grimes int
1044b88c807SRodney W. Grimes cpio_trail(arcn)
1054b88c807SRodney W. Grimes 	register ARCHD *arcn;
1064b88c807SRodney W. Grimes #endif
1074b88c807SRodney W. Grimes {
1084b88c807SRodney W. Grimes 	/*
1094b88c807SRodney W. Grimes 	 * look for trailer id in file we are about to process
1104b88c807SRodney W. Grimes 	 */
1114b88c807SRodney W. Grimes 	if ((strcmp(arcn->name, TRAILER) == 0) && (arcn->sb.st_size == 0))
1124b88c807SRodney W. Grimes 		return(0);
1134b88c807SRodney W. Grimes 	return(-1);
1144b88c807SRodney W. Grimes }
1154b88c807SRodney W. Grimes 
1164b88c807SRodney W. Grimes /*
1174b88c807SRodney W. Grimes  * com_rd()
1184b88c807SRodney W. Grimes  *	operations common to all cpio read functions.
1194b88c807SRodney W. Grimes  * Return:
1204b88c807SRodney W. Grimes  *	0
1214b88c807SRodney W. Grimes  */
1224b88c807SRodney W. Grimes 
123778766feSKris Kennaway #ifdef __STDC__
1244b88c807SRodney W. Grimes static int
1254b88c807SRodney W. Grimes com_rd(register ARCHD *arcn)
1264b88c807SRodney W. Grimes #else
1274b88c807SRodney W. Grimes static int
1284b88c807SRodney W. Grimes com_rd(arcn)
1294b88c807SRodney W. Grimes 	register ARCHD *arcn;
1304b88c807SRodney W. Grimes #endif
1314b88c807SRodney W. Grimes {
1324b88c807SRodney W. Grimes 	arcn->skip = 0;
1334b88c807SRodney W. Grimes 	arcn->pat = NULL;
1344b88c807SRodney W. Grimes 	arcn->org_name = arcn->name;
1354b88c807SRodney W. Grimes 	switch(arcn->sb.st_mode & C_IFMT) {
1364b88c807SRodney W. Grimes 	case C_ISFIFO:
1374b88c807SRodney W. Grimes 		arcn->type = PAX_FIF;
1384b88c807SRodney W. Grimes 		break;
1394b88c807SRodney W. Grimes 	case C_ISDIR:
1404b88c807SRodney W. Grimes 		arcn->type = PAX_DIR;
1414b88c807SRodney W. Grimes 		break;
1424b88c807SRodney W. Grimes 	case C_ISBLK:
1434b88c807SRodney W. Grimes 		arcn->type = PAX_BLK;
1444b88c807SRodney W. Grimes 		break;
1454b88c807SRodney W. Grimes 	case C_ISCHR:
1464b88c807SRodney W. Grimes 		arcn->type = PAX_CHR;
1474b88c807SRodney W. Grimes 		break;
1484b88c807SRodney W. Grimes 	case C_ISLNK:
1494b88c807SRodney W. Grimes 		arcn->type = PAX_SLK;
1504b88c807SRodney W. Grimes 		break;
1514b88c807SRodney W. Grimes 	case C_ISOCK:
1524b88c807SRodney W. Grimes 		arcn->type = PAX_SCK;
1534b88c807SRodney W. Grimes 		break;
1544b88c807SRodney W. Grimes 	case C_ISCTG:
1554b88c807SRodney W. Grimes 	case C_ISREG:
1564b88c807SRodney W. Grimes 	default:
1574b88c807SRodney W. Grimes 		/*
1584b88c807SRodney W. Grimes 		 * we have file data, set up skip (pad is set in the format
1594b88c807SRodney W. Grimes 		 * specific sections)
1604b88c807SRodney W. Grimes 		 */
1614b88c807SRodney W. Grimes 		arcn->sb.st_mode = (arcn->sb.st_mode & 0xfff) | C_ISREG;
1624b88c807SRodney W. Grimes 		arcn->type = PAX_REG;
1634b88c807SRodney W. Grimes 		arcn->skip = arcn->sb.st_size;
1644b88c807SRodney W. Grimes 		break;
1654b88c807SRodney W. Grimes 	}
1664b88c807SRodney W. Grimes 	if (chk_lnk(arcn) < 0)
1674b88c807SRodney W. Grimes 		return(-1);
1684b88c807SRodney W. Grimes 	return(0);
1694b88c807SRodney W. Grimes }
1704b88c807SRodney W. Grimes 
1714b88c807SRodney W. Grimes /*
1724b88c807SRodney W. Grimes  * cpio_end_wr()
1734b88c807SRodney W. Grimes  *	write the special file with the name trailer in the proper format
1744b88c807SRodney W. Grimes  * Return:
1754b88c807SRodney W. Grimes  *	result of the write of the trailer from the cpio specific write func
1764b88c807SRodney W. Grimes  */
1774b88c807SRodney W. Grimes 
178778766feSKris Kennaway #ifdef __STDC__
1794b88c807SRodney W. Grimes int
1804b88c807SRodney W. Grimes cpio_endwr(void)
1814b88c807SRodney W. Grimes #else
1824b88c807SRodney W. Grimes int
1834b88c807SRodney W. Grimes cpio_endwr()
1844b88c807SRodney W. Grimes #endif
1854b88c807SRodney W. Grimes {
1864b88c807SRodney W. Grimes 	ARCHD last;
1874b88c807SRodney W. Grimes 
1884b88c807SRodney W. Grimes 	/*
1894b88c807SRodney W. Grimes 	 * create a trailer request and call the proper format write function
1904b88c807SRodney W. Grimes 	 */
191778766feSKris Kennaway 	memset(&last, 0, sizeof(last));
1924b88c807SRodney W. Grimes 	last.nlen = sizeof(TRAILER) - 1;
1934b88c807SRodney W. Grimes 	last.type = PAX_REG;
1944b88c807SRodney W. Grimes 	last.sb.st_nlink = 1;
1954b88c807SRodney W. Grimes 	(void)strcpy(last.name, TRAILER);
1964b88c807SRodney W. Grimes 	return((*frmt->wr)(&last));
1974b88c807SRodney W. Grimes }
1984b88c807SRodney W. Grimes 
1994b88c807SRodney W. Grimes /*
2004b88c807SRodney W. Grimes  * rd_nam()
2014b88c807SRodney W. Grimes  *	read in the file name which follows the cpio header
2024b88c807SRodney W. Grimes  * Return:
2034b88c807SRodney W. Grimes  *	0 if ok, -1 otherwise
2044b88c807SRodney W. Grimes  */
2054b88c807SRodney W. Grimes 
206778766feSKris Kennaway #ifdef __STDC__
2074b88c807SRodney W. Grimes static int
2084b88c807SRodney W. Grimes rd_nm(register ARCHD *arcn, int nsz)
2094b88c807SRodney W. Grimes #else
2104b88c807SRodney W. Grimes static int
2114b88c807SRodney W. Grimes rd_nm(arcn, nsz)
2124b88c807SRodney W. Grimes 	register ARCHD *arcn;
2134b88c807SRodney W. Grimes 	int nsz;
2144b88c807SRodney W. Grimes #endif
2154b88c807SRodney W. Grimes {
2164b88c807SRodney W. Grimes 	/*
2174b88c807SRodney W. Grimes 	 * do not even try bogus values
2184b88c807SRodney W. Grimes 	 */
2194b88c807SRodney W. Grimes 	if ((nsz == 0) || (nsz > sizeof(arcn->name))) {
220778766feSKris Kennaway 		paxwarn(1, "Cpio file name length %d is out of range", nsz);
2214b88c807SRodney W. Grimes 		return(-1);
2224b88c807SRodney W. Grimes 	}
2234b88c807SRodney W. Grimes 
2244b88c807SRodney W. Grimes 	/*
2254b88c807SRodney W. Grimes 	 * read the name and make sure it is not empty and is \0 terminated
2264b88c807SRodney W. Grimes 	 */
2274b88c807SRodney W. Grimes 	if ((rd_wrbuf(arcn->name,nsz) != nsz) || (arcn->name[nsz-1] != '\0') ||
2284b88c807SRodney W. Grimes 	    (arcn->name[0] == '\0')) {
229778766feSKris Kennaway 		paxwarn(1, "Cpio file name in header is corrupted");
2304b88c807SRodney W. Grimes 		return(-1);
2314b88c807SRodney W. Grimes 	}
2324b88c807SRodney W. Grimes 	return(0);
2334b88c807SRodney W. Grimes }
2344b88c807SRodney W. Grimes 
2354b88c807SRodney W. Grimes /*
2364b88c807SRodney W. Grimes  * rd_ln_nm()
2374b88c807SRodney W. Grimes  *	read in the link name for a file with links. The link name is stored
2384b88c807SRodney W. Grimes  *	like file data (and is NOT \0 terminated!)
2394b88c807SRodney W. Grimes  * Return:
2404b88c807SRodney W. Grimes  *	0 if ok, -1 otherwise
2414b88c807SRodney W. Grimes  */
2424b88c807SRodney W. Grimes 
243778766feSKris Kennaway #ifdef __STDC__
2444b88c807SRodney W. Grimes static int
2454b88c807SRodney W. Grimes rd_ln_nm(register ARCHD *arcn)
2464b88c807SRodney W. Grimes #else
2474b88c807SRodney W. Grimes static int
2484b88c807SRodney W. Grimes rd_ln_nm(arcn)
2494b88c807SRodney W. Grimes 	register ARCHD *arcn;
2504b88c807SRodney W. Grimes #endif
2514b88c807SRodney W. Grimes {
2524b88c807SRodney W. Grimes 	/*
2534b88c807SRodney W. Grimes 	 * check the length specified for bogus values
2544b88c807SRodney W. Grimes 	 */
2554b88c807SRodney W. Grimes 	if ((arcn->sb.st_size == 0) ||
2564b88c807SRodney W. Grimes 	    (arcn->sb.st_size >= sizeof(arcn->ln_name))) {
2574b88c807SRodney W. Grimes #		ifdef NET2_STAT
258778766feSKris Kennaway 		paxwarn(1, "Cpio link name length is invalid: %lu",
2594b88c807SRodney W. Grimes 		    arcn->sb.st_size);
2604b88c807SRodney W. Grimes #		else
261778766feSKris Kennaway 		paxwarn(1, "Cpio link name length is invalid: %qu",
2624b88c807SRodney W. Grimes 		    arcn->sb.st_size);
2634b88c807SRodney W. Grimes #		endif
2644b88c807SRodney W. Grimes 		return(-1);
2654b88c807SRodney W. Grimes 	}
2664b88c807SRodney W. Grimes 
2674b88c807SRodney W. Grimes 	/*
2684b88c807SRodney W. Grimes 	 * read in the link name and \0 terminate it
2694b88c807SRodney W. Grimes 	 */
2704b88c807SRodney W. Grimes 	if (rd_wrbuf(arcn->ln_name, (int)arcn->sb.st_size) !=
2714b88c807SRodney W. Grimes 	    (int)arcn->sb.st_size) {
272778766feSKris Kennaway 		paxwarn(1, "Cpio link name read error");
2734b88c807SRodney W. Grimes 		return(-1);
2744b88c807SRodney W. Grimes 	}
2754b88c807SRodney W. Grimes 	arcn->ln_nlen = arcn->sb.st_size;
2764b88c807SRodney W. Grimes 	arcn->ln_name[arcn->ln_nlen] = '\0';
2774b88c807SRodney W. Grimes 
2784b88c807SRodney W. Grimes 	/*
2794b88c807SRodney W. Grimes 	 * watch out for those empty link names
2804b88c807SRodney W. Grimes 	 */
2814b88c807SRodney W. Grimes 	if (arcn->ln_name[0] == '\0') {
282778766feSKris Kennaway 		paxwarn(1, "Cpio link name is corrupt");
2834b88c807SRodney W. Grimes 		return(-1);
2844b88c807SRodney W. Grimes 	}
2854b88c807SRodney W. Grimes 	return(0);
2864b88c807SRodney W. Grimes }
2874b88c807SRodney W. Grimes 
2884b88c807SRodney W. Grimes /*
2894b88c807SRodney W. Grimes  * Routines common to the extended byte oriented cpio format
2904b88c807SRodney W. Grimes  */
2914b88c807SRodney W. Grimes 
2924b88c807SRodney W. Grimes /*
2934b88c807SRodney W. Grimes  * cpio_id()
2944b88c807SRodney W. Grimes  *      determine if a block given to us is a valid extended byte oriented
2954b88c807SRodney W. Grimes  *	cpio header
2964b88c807SRodney W. Grimes  * Return:
2974b88c807SRodney W. Grimes  *      0 if a valid header, -1 otherwise
2984b88c807SRodney W. Grimes  */
2994b88c807SRodney W. Grimes 
300778766feSKris Kennaway #ifdef __STDC__
3014b88c807SRodney W. Grimes int
3024b88c807SRodney W. Grimes cpio_id(char *blk, int size)
3034b88c807SRodney W. Grimes #else
3044b88c807SRodney W. Grimes int
3054b88c807SRodney W. Grimes cpio_id(blk, size)
3064b88c807SRodney W. Grimes 	char *blk;
3074b88c807SRodney W. Grimes 	int size;
3084b88c807SRodney W. Grimes #endif
3094b88c807SRodney W. Grimes {
3104b88c807SRodney W. Grimes 	if ((size < sizeof(HD_CPIO)) ||
3114b88c807SRodney W. Grimes 	    (strncmp(blk, AMAGIC, sizeof(AMAGIC) - 1) != 0))
3124b88c807SRodney W. Grimes 		return(-1);
3134b88c807SRodney W. Grimes 	return(0);
3144b88c807SRodney W. Grimes }
3154b88c807SRodney W. Grimes 
3164b88c807SRodney W. Grimes /*
3174b88c807SRodney W. Grimes  * cpio_rd()
3184b88c807SRodney W. Grimes  *	determine if a buffer is a byte oriented extended cpio archive entry.
3194b88c807SRodney W. Grimes  *	convert and store the values in the ARCHD parameter.
3204b88c807SRodney W. Grimes  * Return:
3214b88c807SRodney W. Grimes  *	0 if a valid header, -1 otherwise.
3224b88c807SRodney W. Grimes  */
3234b88c807SRodney W. Grimes 
324778766feSKris Kennaway #ifdef __STDC__
3254b88c807SRodney W. Grimes int
3264b88c807SRodney W. Grimes cpio_rd(register ARCHD *arcn, register char *buf)
3274b88c807SRodney W. Grimes #else
3284b88c807SRodney W. Grimes int
3294b88c807SRodney W. Grimes cpio_rd(arcn, buf)
3304b88c807SRodney W. Grimes 	register ARCHD *arcn;
3314b88c807SRodney W. Grimes 	register char *buf;
3324b88c807SRodney W. Grimes #endif
3334b88c807SRodney W. Grimes {
3344b88c807SRodney W. Grimes 	register int nsz;
3354b88c807SRodney W. Grimes 	register HD_CPIO *hd;
3364b88c807SRodney W. Grimes 
3374b88c807SRodney W. Grimes 	/*
3384b88c807SRodney W. Grimes 	 * check that this is a valid header, if not return -1
3394b88c807SRodney W. Grimes 	 */
3404b88c807SRodney W. Grimes 	if (cpio_id(buf, sizeof(HD_CPIO)) < 0)
3414b88c807SRodney W. Grimes 		return(-1);
3424b88c807SRodney W. Grimes 	hd = (HD_CPIO *)buf;
3434b88c807SRodney W. Grimes 
3444b88c807SRodney W. Grimes 	/*
3454b88c807SRodney W. Grimes 	 * byte oriented cpio (posix) does not have padding! extract the octal
3464b88c807SRodney W. Grimes 	 * ascii fields from the header
3474b88c807SRodney W. Grimes 	 */
3484b88c807SRodney W. Grimes 	arcn->pad = 0L;
3494b88c807SRodney W. Grimes 	arcn->sb.st_dev = (dev_t)asc_ul(hd->c_dev, sizeof(hd->c_dev), OCT);
3504b88c807SRodney W. Grimes 	arcn->sb.st_ino = (ino_t)asc_ul(hd->c_ino, sizeof(hd->c_ino), OCT);
3514b88c807SRodney W. Grimes 	arcn->sb.st_mode = (mode_t)asc_ul(hd->c_mode, sizeof(hd->c_mode), OCT);
3524b88c807SRodney W. Grimes 	arcn->sb.st_uid = (uid_t)asc_ul(hd->c_uid, sizeof(hd->c_uid), OCT);
3534b88c807SRodney W. Grimes 	arcn->sb.st_gid = (gid_t)asc_ul(hd->c_gid, sizeof(hd->c_gid), OCT);
3544b88c807SRodney W. Grimes 	arcn->sb.st_nlink = (nlink_t)asc_ul(hd->c_nlink, sizeof(hd->c_nlink),
3554b88c807SRodney W. Grimes 	    OCT);
3564b88c807SRodney W. Grimes 	arcn->sb.st_rdev = (dev_t)asc_ul(hd->c_rdev, sizeof(hd->c_rdev), OCT);
3574b88c807SRodney W. Grimes 	arcn->sb.st_mtime = (time_t)asc_ul(hd->c_mtime, sizeof(hd->c_mtime),
3584b88c807SRodney W. Grimes 	    OCT);
3594b88c807SRodney W. Grimes 	arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime;
3604b88c807SRodney W. Grimes #	ifdef NET2_STAT
3614b88c807SRodney W. Grimes 	arcn->sb.st_size = (off_t)asc_ul(hd->c_filesize,sizeof(hd->c_filesize),
3624b88c807SRodney W. Grimes 	    OCT);
3634b88c807SRodney W. Grimes #	else
3644b88c807SRodney W. Grimes 	arcn->sb.st_size = (off_t)asc_uqd(hd->c_filesize,sizeof(hd->c_filesize),
3654b88c807SRodney W. Grimes 	    OCT);
3664b88c807SRodney W. Grimes #	endif
3674b88c807SRodney W. Grimes 
3684b88c807SRodney W. Grimes 	/*
3694b88c807SRodney W. Grimes 	 * check name size and if valid, read in the name of this entry (name
3704b88c807SRodney W. Grimes 	 * follows header in the archive)
3714b88c807SRodney W. Grimes 	 */
3724b88c807SRodney W. Grimes 	if ((nsz = (int)asc_ul(hd->c_namesize,sizeof(hd->c_namesize),OCT)) < 2)
3734b88c807SRodney W. Grimes 		return(-1);
3744b88c807SRodney W. Grimes 	arcn->nlen = nsz - 1;
3754b88c807SRodney W. Grimes 	if (rd_nm(arcn, nsz) < 0)
3764b88c807SRodney W. Grimes 		return(-1);
3774b88c807SRodney W. Grimes 
3784b88c807SRodney W. Grimes 	if (((arcn->sb.st_mode&C_IFMT) != C_ISLNK)||(arcn->sb.st_size == 0)) {
3794b88c807SRodney W. Grimes 		/*
3804b88c807SRodney W. Grimes 	 	 * no link name to read for this file
3814b88c807SRodney W. Grimes 	 	 */
3824b88c807SRodney W. Grimes 		arcn->ln_nlen = 0;
3834b88c807SRodney W. Grimes 		arcn->ln_name[0] = '\0';
3844b88c807SRodney W. Grimes 		return(com_rd(arcn));
3854b88c807SRodney W. Grimes 	}
3864b88c807SRodney W. Grimes 
3874b88c807SRodney W. Grimes 	/*
3884b88c807SRodney W. Grimes 	 * check link name size and read in the link name. Link names are
3894b88c807SRodney W. Grimes 	 * stored like file data.
3904b88c807SRodney W. Grimes 	 */
3914b88c807SRodney W. Grimes 	if (rd_ln_nm(arcn) < 0)
3924b88c807SRodney W. Grimes 		return(-1);
3934b88c807SRodney W. Grimes 
3944b88c807SRodney W. Grimes 	/*
3954b88c807SRodney W. Grimes 	 * we have a valid header (with a link)
3964b88c807SRodney W. Grimes 	 */
3974b88c807SRodney W. Grimes 	return(com_rd(arcn));
3984b88c807SRodney W. Grimes }
3994b88c807SRodney W. Grimes 
4004b88c807SRodney W. Grimes /*
4014b88c807SRodney W. Grimes  * cpio_endrd()
4024b88c807SRodney W. Grimes  *      no cleanup needed here, just return size of the trailer (for append)
4034b88c807SRodney W. Grimes  * Return:
4044b88c807SRodney W. Grimes  *      size of trailer header in this format
4054b88c807SRodney W. Grimes  */
4064b88c807SRodney W. Grimes 
407778766feSKris Kennaway #ifdef __STDC__
4084b88c807SRodney W. Grimes off_t
4094b88c807SRodney W. Grimes cpio_endrd(void)
4104b88c807SRodney W. Grimes #else
4114b88c807SRodney W. Grimes off_t
4124b88c807SRodney W. Grimes cpio_endrd()
4134b88c807SRodney W. Grimes #endif
4144b88c807SRodney W. Grimes {
4154b88c807SRodney W. Grimes 	return((off_t)(sizeof(HD_CPIO) + sizeof(TRAILER)));
4164b88c807SRodney W. Grimes }
4174b88c807SRodney W. Grimes 
4184b88c807SRodney W. Grimes /*
4194b88c807SRodney W. Grimes  * cpio_stwr()
4204b88c807SRodney W. Grimes  *	start up the device mapping table
4214b88c807SRodney W. Grimes  * Return:
4224b88c807SRodney W. Grimes  *	0 if ok, -1 otherwise (what dev_start() returns)
4234b88c807SRodney W. Grimes  */
4244b88c807SRodney W. Grimes 
425778766feSKris Kennaway #ifdef __STDC__
4264b88c807SRodney W. Grimes int
4274b88c807SRodney W. Grimes cpio_stwr(void)
4284b88c807SRodney W. Grimes #else
4294b88c807SRodney W. Grimes int
4304b88c807SRodney W. Grimes cpio_stwr()
4314b88c807SRodney W. Grimes #endif
4324b88c807SRodney W. Grimes {
4334b88c807SRodney W. Grimes 	return(dev_start());
4344b88c807SRodney W. Grimes }
4354b88c807SRodney W. Grimes 
4364b88c807SRodney W. Grimes /*
4374b88c807SRodney W. Grimes  * cpio_wr()
4384b88c807SRodney W. Grimes  *	copy the data in the ARCHD to buffer in extended byte oriented cpio
4394b88c807SRodney W. Grimes  *	format.
4404b88c807SRodney W. Grimes  * Return
4414b88c807SRodney W. Grimes  *      0 if file has data to be written after the header, 1 if file has NO
4424b88c807SRodney W. Grimes  *	data to write after the header, -1 if archive write failed
4434b88c807SRodney W. Grimes  */
4444b88c807SRodney W. Grimes 
445778766feSKris Kennaway #ifdef __STDC__
4464b88c807SRodney W. Grimes int
4474b88c807SRodney W. Grimes cpio_wr(register ARCHD *arcn)
4484b88c807SRodney W. Grimes #else
4494b88c807SRodney W. Grimes int
4504b88c807SRodney W. Grimes cpio_wr(arcn)
4514b88c807SRodney W. Grimes 	register ARCHD *arcn;
4524b88c807SRodney W. Grimes #endif
4534b88c807SRodney W. Grimes {
4544b88c807SRodney W. Grimes 	register HD_CPIO *hd;
4554b88c807SRodney W. Grimes 	register int nsz;
4564b88c807SRodney W. Grimes 	char hdblk[sizeof(HD_CPIO)];
4574b88c807SRodney W. Grimes 
4584b88c807SRodney W. Grimes 	/*
4594b88c807SRodney W. Grimes 	 * check and repair truncated device and inode fields in the header
4604b88c807SRodney W. Grimes 	 */
4614b88c807SRodney W. Grimes 	if (map_dev(arcn, (u_long)CPIO_MASK, (u_long)CPIO_MASK) < 0)
4624b88c807SRodney W. Grimes 		return(-1);
4634b88c807SRodney W. Grimes 
4644b88c807SRodney W. Grimes 	arcn->pad = 0L;
4654b88c807SRodney W. Grimes 	nsz = arcn->nlen + 1;
4664b88c807SRodney W. Grimes 	hd = (HD_CPIO *)hdblk;
4674b88c807SRodney W. Grimes 	if ((arcn->type != PAX_BLK) && (arcn->type != PAX_CHR))
4684b88c807SRodney W. Grimes 		arcn->sb.st_rdev = 0;
4694b88c807SRodney W. Grimes 
4704b88c807SRodney W. Grimes 	switch(arcn->type) {
4714b88c807SRodney W. Grimes 	case PAX_CTG:
4724b88c807SRodney W. Grimes 	case PAX_REG:
4734b88c807SRodney W. Grimes 	case PAX_HRG:
4744b88c807SRodney W. Grimes 		/*
4754b88c807SRodney W. Grimes 		 * set data size for file data
4764b88c807SRodney W. Grimes 		 */
4774b88c807SRodney W. Grimes #		ifdef NET2_STAT
4784b88c807SRodney W. Grimes 		if (ul_asc((u_long)arcn->sb.st_size, hd->c_filesize,
4794b88c807SRodney W. Grimes 		    sizeof(hd->c_filesize), OCT)) {
4804b88c807SRodney W. Grimes #		else
4814b88c807SRodney W. Grimes 		if (uqd_asc((u_quad_t)arcn->sb.st_size, hd->c_filesize,
4824b88c807SRodney W. Grimes 		    sizeof(hd->c_filesize), OCT)) {
4834b88c807SRodney W. Grimes #		endif
484778766feSKris Kennaway 			paxwarn(1,"File is too large for cpio format %s",
4854b88c807SRodney W. Grimes 			    arcn->org_name);
4864b88c807SRodney W. Grimes 			return(1);
4874b88c807SRodney W. Grimes 		}
4884b88c807SRodney W. Grimes 		break;
4894b88c807SRodney W. Grimes 	case PAX_SLK:
4904b88c807SRodney W. Grimes 		/*
4914b88c807SRodney W. Grimes 		 * set data size to hold link name
4924b88c807SRodney W. Grimes 		 */
4934b88c807SRodney W. Grimes 		if (ul_asc((u_long)arcn->ln_nlen, hd->c_filesize,
4944b88c807SRodney W. Grimes 		    sizeof(hd->c_filesize), OCT))
4954b88c807SRodney W. Grimes 			goto out;
4964b88c807SRodney W. Grimes 		break;
4974b88c807SRodney W. Grimes 	default:
4984b88c807SRodney W. Grimes 		/*
4994b88c807SRodney W. Grimes 		 * all other file types have no file data
5004b88c807SRodney W. Grimes 		 */
5014b88c807SRodney W. Grimes 		if (ul_asc((u_long)0, hd->c_filesize, sizeof(hd->c_filesize),
5024b88c807SRodney W. Grimes 		     OCT))
5034b88c807SRodney W. Grimes 			goto out;
5044b88c807SRodney W. Grimes 		break;
5054b88c807SRodney W. Grimes 	}
5064b88c807SRodney W. Grimes 
5074b88c807SRodney W. Grimes 	/*
5084b88c807SRodney W. Grimes 	 * copy the values to the header using octal ascii
5094b88c807SRodney W. Grimes 	 */
5104b88c807SRodney W. Grimes 	if (ul_asc((u_long)MAGIC, hd->c_magic, sizeof(hd->c_magic), OCT) ||
5114b88c807SRodney W. Grimes 	    ul_asc((u_long)arcn->sb.st_dev, hd->c_dev, sizeof(hd->c_dev),
5124b88c807SRodney W. Grimes 	        OCT) ||
5134b88c807SRodney W. Grimes 	    ul_asc((u_long)arcn->sb.st_ino, hd->c_ino, sizeof(hd->c_ino),
5144b88c807SRodney W. Grimes 		OCT) ||
5154b88c807SRodney W. Grimes 	    ul_asc((u_long)arcn->sb.st_mode, hd->c_mode, sizeof(hd->c_mode),
5164b88c807SRodney W. Grimes 		OCT) ||
5174b88c807SRodney W. Grimes 	    ul_asc((u_long)arcn->sb.st_uid, hd->c_uid, sizeof(hd->c_uid),
5184b88c807SRodney W. Grimes 		OCT) ||
5194b88c807SRodney W. Grimes 	    ul_asc((u_long)arcn->sb.st_gid, hd->c_gid, sizeof(hd->c_gid),
5204b88c807SRodney W. Grimes 		OCT) ||
5214b88c807SRodney W. Grimes 	    ul_asc((u_long)arcn->sb.st_nlink, hd->c_nlink, sizeof(hd->c_nlink),
5224b88c807SRodney W. Grimes 		 OCT) ||
5234b88c807SRodney W. Grimes 	    ul_asc((u_long)arcn->sb.st_rdev, hd->c_rdev, sizeof(hd->c_rdev),
5244b88c807SRodney W. Grimes 		OCT) ||
5254b88c807SRodney W. Grimes 	    ul_asc((u_long)arcn->sb.st_mtime,hd->c_mtime,sizeof(hd->c_mtime),
5264b88c807SRodney W. Grimes 		OCT) ||
5274b88c807SRodney W. Grimes 	    ul_asc((u_long)nsz, hd->c_namesize, sizeof(hd->c_namesize), OCT))
5284b88c807SRodney W. Grimes 		goto out;
5294b88c807SRodney W. Grimes 
5304b88c807SRodney W. Grimes 	/*
5314b88c807SRodney W. Grimes 	 * write the file name to the archive
5324b88c807SRodney W. Grimes 	 */
5334b88c807SRodney W. Grimes 	if ((wr_rdbuf(hdblk, (int)sizeof(HD_CPIO)) < 0) ||
5344b88c807SRodney W. Grimes 	    (wr_rdbuf(arcn->name, nsz) < 0)) {
535778766feSKris Kennaway 		paxwarn(1, "Unable to write cpio header for %s", arcn->org_name);
5364b88c807SRodney W. Grimes 		return(-1);
5374b88c807SRodney W. Grimes 	}
5384b88c807SRodney W. Grimes 
5394b88c807SRodney W. Grimes 	/*
5404b88c807SRodney W. Grimes 	 * if this file has data, we are done. The caller will write the file
5414b88c807SRodney W. Grimes 	 * data, if we are link tell caller we are done, go to next file
5424b88c807SRodney W. Grimes 	 */
5434b88c807SRodney W. Grimes 	if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG) ||
5444b88c807SRodney W. Grimes 	    (arcn->type == PAX_HRG))
5454b88c807SRodney W. Grimes 		return(0);
5464b88c807SRodney W. Grimes 	if (arcn->type != PAX_SLK)
5474b88c807SRodney W. Grimes 		return(1);
5484b88c807SRodney W. Grimes 
5494b88c807SRodney W. Grimes 	/*
5504b88c807SRodney W. Grimes 	 * write the link name to the archive, tell the caller to go to the
5514b88c807SRodney W. Grimes 	 * next file as we are done.
5524b88c807SRodney W. Grimes 	 */
5534b88c807SRodney W. Grimes 	if (wr_rdbuf(arcn->ln_name, arcn->ln_nlen) < 0) {
554778766feSKris Kennaway 		paxwarn(1,"Unable to write cpio link name for %s",arcn->org_name);
5554b88c807SRodney W. Grimes 		return(-1);
5564b88c807SRodney W. Grimes 	}
5574b88c807SRodney W. Grimes 	return(1);
5584b88c807SRodney W. Grimes 
5594b88c807SRodney W. Grimes     out:
5604b88c807SRodney W. Grimes 	/*
5614b88c807SRodney W. Grimes 	 * header field is out of range
5624b88c807SRodney W. Grimes 	 */
563778766feSKris Kennaway 	paxwarn(1, "Cpio header field is too small to store file %s",
5644b88c807SRodney W. Grimes 	    arcn->org_name);
5654b88c807SRodney W. Grimes 	return(1);
5664b88c807SRodney W. Grimes }
5674b88c807SRodney W. Grimes 
5684b88c807SRodney W. Grimes /*
5694b88c807SRodney W. Grimes  * Routines common to the system VR4 version of cpio (with/without file CRC)
5704b88c807SRodney W. Grimes  */
5714b88c807SRodney W. Grimes 
5724b88c807SRodney W. Grimes /*
5734b88c807SRodney W. Grimes  * vcpio_id()
5744b88c807SRodney W. Grimes  *      determine if a block given to us is a valid system VR4 cpio header
5754b88c807SRodney W. Grimes  *	WITHOUT crc. WATCH it the magic cookies are in OCTAL, the header
5764b88c807SRodney W. Grimes  *	uses HEX
5774b88c807SRodney W. Grimes  * Return:
5784b88c807SRodney W. Grimes  *      0 if a valid header, -1 otherwise
5794b88c807SRodney W. Grimes  */
5804b88c807SRodney W. Grimes 
581778766feSKris Kennaway #ifdef __STDC__
5824b88c807SRodney W. Grimes int
5834b88c807SRodney W. Grimes vcpio_id(char *blk, int size)
5844b88c807SRodney W. Grimes #else
5854b88c807SRodney W. Grimes int
5864b88c807SRodney W. Grimes vcpio_id(blk, size)
5874b88c807SRodney W. Grimes 	char *blk;
5884b88c807SRodney W. Grimes 	int size;
5894b88c807SRodney W. Grimes #endif
5904b88c807SRodney W. Grimes {
5914b88c807SRodney W. Grimes 	if ((size < sizeof(HD_VCPIO)) ||
5924b88c807SRodney W. Grimes 	    (strncmp(blk, AVMAGIC, sizeof(AVMAGIC) - 1) != 0))
5934b88c807SRodney W. Grimes 		return(-1);
5944b88c807SRodney W. Grimes 	return(0);
5954b88c807SRodney W. Grimes }
5964b88c807SRodney W. Grimes 
5974b88c807SRodney W. Grimes /*
5984b88c807SRodney W. Grimes  * crc_id()
5994b88c807SRodney W. Grimes  *      determine if a block given to us is a valid system VR4 cpio header
6004b88c807SRodney W. Grimes  *	WITH crc. WATCH it the magic cookies are in OCTAL the header uses HEX
6014b88c807SRodney W. Grimes  * Return:
6024b88c807SRodney W. Grimes  *      0 if a valid header, -1 otherwise
6034b88c807SRodney W. Grimes  */
6044b88c807SRodney W. Grimes 
605778766feSKris Kennaway #ifdef __STDC__
6064b88c807SRodney W. Grimes int
6074b88c807SRodney W. Grimes crc_id(char *blk, int size)
6084b88c807SRodney W. Grimes #else
6094b88c807SRodney W. Grimes int
6104b88c807SRodney W. Grimes crc_id(blk, size)
6114b88c807SRodney W. Grimes 	char *blk;
6124b88c807SRodney W. Grimes 	int size;
6134b88c807SRodney W. Grimes #endif
6144b88c807SRodney W. Grimes {
6154b88c807SRodney W. Grimes 	if ((size < sizeof(HD_VCPIO)) ||
6164b88c807SRodney W. Grimes 	    (strncmp(blk, AVCMAGIC, sizeof(AVCMAGIC) - 1) != 0))
6174b88c807SRodney W. Grimes 		return(-1);
6184b88c807SRodney W. Grimes 	return(0);
6194b88c807SRodney W. Grimes }
6204b88c807SRodney W. Grimes 
6214b88c807SRodney W. Grimes /*
6224b88c807SRodney W. Grimes  * crc_strd()
6234b88c807SRodney W. Grimes  w	set file data CRC calculations. Fire up the hard link detection code
6244b88c807SRodney W. Grimes  * Return:
6254b88c807SRodney W. Grimes  *      0 if ok -1 otherwise (the return values of lnk_start())
6264b88c807SRodney W. Grimes  */
6274b88c807SRodney W. Grimes 
628778766feSKris Kennaway #ifdef __STDC__
6294b88c807SRodney W. Grimes int
6304b88c807SRodney W. Grimes crc_strd(void)
6314b88c807SRodney W. Grimes #else
6324b88c807SRodney W. Grimes int
6334b88c807SRodney W. Grimes crc_strd()
6344b88c807SRodney W. Grimes #endif
6354b88c807SRodney W. Grimes {
6364b88c807SRodney W. Grimes 	docrc = 1;
6374b88c807SRodney W. Grimes 	return(lnk_start());
6384b88c807SRodney W. Grimes }
6394b88c807SRodney W. Grimes 
6404b88c807SRodney W. Grimes /*
6414b88c807SRodney W. Grimes  * vcpio_rd()
6424b88c807SRodney W. Grimes  *	determine if a buffer is a system VR4 archive entry. (with/without CRC)
6434b88c807SRodney W. Grimes  *	convert and store the values in the ARCHD parameter.
6444b88c807SRodney W. Grimes  * Return:
6454b88c807SRodney W. Grimes  *	0 if a valid header, -1 otherwise.
6464b88c807SRodney W. Grimes  */
6474b88c807SRodney W. Grimes 
648778766feSKris Kennaway #ifdef __STDC__
6494b88c807SRodney W. Grimes int
6504b88c807SRodney W. Grimes vcpio_rd(register ARCHD *arcn, register char *buf)
6514b88c807SRodney W. Grimes #else
6524b88c807SRodney W. Grimes int
6534b88c807SRodney W. Grimes vcpio_rd(arcn, buf)
6544b88c807SRodney W. Grimes 	register ARCHD *arcn;
6554b88c807SRodney W. Grimes 	register char *buf;
6564b88c807SRodney W. Grimes #endif
6574b88c807SRodney W. Grimes {
6584b88c807SRodney W. Grimes 	register HD_VCPIO *hd;
6594b88c807SRodney W. Grimes 	dev_t devminor;
6604b88c807SRodney W. Grimes 	dev_t devmajor;
6614b88c807SRodney W. Grimes 	register int nsz;
6624b88c807SRodney W. Grimes 
6634b88c807SRodney W. Grimes 	/*
6644b88c807SRodney W. Grimes 	 * during the id phase it was determined if we were using CRC, use the
6654b88c807SRodney W. Grimes 	 * proper id routine.
6664b88c807SRodney W. Grimes 	 */
6674b88c807SRodney W. Grimes 	if (docrc) {
6684b88c807SRodney W. Grimes 		if (crc_id(buf, sizeof(HD_VCPIO)) < 0)
6694b88c807SRodney W. Grimes 			return(-1);
6704b88c807SRodney W. Grimes 	} else {
6714b88c807SRodney W. Grimes 		if (vcpio_id(buf, sizeof(HD_VCPIO)) < 0)
6724b88c807SRodney W. Grimes 			return(-1);
6734b88c807SRodney W. Grimes 	}
6744b88c807SRodney W. Grimes 
6754b88c807SRodney W. Grimes 	hd = (HD_VCPIO *)buf;
6764b88c807SRodney W. Grimes 	arcn->pad = 0L;
6774b88c807SRodney W. Grimes 
6784b88c807SRodney W. Grimes 	/*
6794b88c807SRodney W. Grimes 	 * extract the hex ascii fields from the header
6804b88c807SRodney W. Grimes 	 */
6814b88c807SRodney W. Grimes 	arcn->sb.st_ino = (ino_t)asc_ul(hd->c_ino, sizeof(hd->c_ino), HEX);
6824b88c807SRodney W. Grimes 	arcn->sb.st_mode = (mode_t)asc_ul(hd->c_mode, sizeof(hd->c_mode), HEX);
6834b88c807SRodney W. Grimes 	arcn->sb.st_uid = (uid_t)asc_ul(hd->c_uid, sizeof(hd->c_uid), HEX);
6844b88c807SRodney W. Grimes 	arcn->sb.st_gid = (gid_t)asc_ul(hd->c_gid, sizeof(hd->c_gid), HEX);
6854b88c807SRodney W. Grimes 	arcn->sb.st_mtime = (time_t)asc_ul(hd->c_mtime,sizeof(hd->c_mtime),HEX);
6864b88c807SRodney W. Grimes 	arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime;
6874b88c807SRodney W. Grimes #	ifdef NET2_STAT
6884b88c807SRodney W. Grimes 	arcn->sb.st_size = (off_t)asc_ul(hd->c_filesize,
6894b88c807SRodney W. Grimes 	    sizeof(hd->c_filesize), HEX);
6904b88c807SRodney W. Grimes #	else
6914b88c807SRodney W. Grimes 	arcn->sb.st_size = (off_t)asc_uqd(hd->c_filesize,
6924b88c807SRodney W. Grimes 	    sizeof(hd->c_filesize), HEX);
6934b88c807SRodney W. Grimes #	endif
6944b88c807SRodney W. Grimes 	arcn->sb.st_nlink = (nlink_t)asc_ul(hd->c_nlink, sizeof(hd->c_nlink),
6954b88c807SRodney W. Grimes 	    HEX);
6964b88c807SRodney W. Grimes 	devmajor = (dev_t)asc_ul(hd->c_maj, sizeof(hd->c_maj), HEX);
6974b88c807SRodney W. Grimes 	devminor = (dev_t)asc_ul(hd->c_min, sizeof(hd->c_min), HEX);
6984b88c807SRodney W. Grimes 	arcn->sb.st_dev = TODEV(devmajor, devminor);
6994b88c807SRodney W. Grimes 	devmajor = (dev_t)asc_ul(hd->c_rmaj, sizeof(hd->c_maj), HEX);
7004b88c807SRodney W. Grimes 	devminor = (dev_t)asc_ul(hd->c_rmin, sizeof(hd->c_min), HEX);
7014b88c807SRodney W. Grimes 	arcn->sb.st_rdev = TODEV(devmajor, devminor);
7024b88c807SRodney W. Grimes 	arcn->crc = asc_ul(hd->c_chksum, sizeof(hd->c_chksum), HEX);
7034b88c807SRodney W. Grimes 
7044b88c807SRodney W. Grimes 	/*
7054b88c807SRodney W. Grimes 	 * check the length of the file name, if ok read it in, return -1 if
7064b88c807SRodney W. Grimes 	 * bogus
7074b88c807SRodney W. Grimes 	 */
7084b88c807SRodney W. Grimes 	if ((nsz = (int)asc_ul(hd->c_namesize,sizeof(hd->c_namesize),HEX)) < 2)
7094b88c807SRodney W. Grimes 		return(-1);
7104b88c807SRodney W. Grimes 	arcn->nlen = nsz - 1;
7114b88c807SRodney W. Grimes 	if (rd_nm(arcn, nsz) < 0)
7124b88c807SRodney W. Grimes 		return(-1);
7134b88c807SRodney W. Grimes 
7144b88c807SRodney W. Grimes 	/*
7154b88c807SRodney W. Grimes 	 * skip padding. header + filename is aligned to 4 byte boundries
7164b88c807SRodney W. Grimes 	 */
7174b88c807SRodney W. Grimes 	if (rd_skip((off_t)(VCPIO_PAD(sizeof(HD_VCPIO) + nsz))) < 0)
7184b88c807SRodney W. Grimes 		return(-1);
7194b88c807SRodney W. Grimes 
7204b88c807SRodney W. Grimes 	/*
7214b88c807SRodney W. Grimes 	 * if not a link (or a file with no data), calculate pad size (for
7224b88c807SRodney W. Grimes 	 * padding which follows the file data), clear the link name and return
7234b88c807SRodney W. Grimes 	 */
7244b88c807SRodney W. Grimes 	if (((arcn->sb.st_mode&C_IFMT) != C_ISLNK)||(arcn->sb.st_size == 0)) {
7254b88c807SRodney W. Grimes 		/*
7264b88c807SRodney W. Grimes 		 * we have a valid header (not a link)
7274b88c807SRodney W. Grimes 		 */
7284b88c807SRodney W. Grimes 		arcn->ln_nlen = 0;
7294b88c807SRodney W. Grimes 		arcn->ln_name[0] = '\0';
7304b88c807SRodney W. Grimes 		arcn->pad = VCPIO_PAD(arcn->sb.st_size);
7314b88c807SRodney W. Grimes 		return(com_rd(arcn));
7324b88c807SRodney W. Grimes 	}
7334b88c807SRodney W. Grimes 
7344b88c807SRodney W. Grimes 	/*
7354b88c807SRodney W. Grimes 	 * read in the link name and skip over the padding
7364b88c807SRodney W. Grimes 	 */
7374b88c807SRodney W. Grimes 	if ((rd_ln_nm(arcn) < 0) ||
7384b88c807SRodney W. Grimes 	    (rd_skip((off_t)(VCPIO_PAD(arcn->sb.st_size))) < 0))
7394b88c807SRodney W. Grimes 		return(-1);
7404b88c807SRodney W. Grimes 
7414b88c807SRodney W. Grimes 	/*
7424b88c807SRodney W. Grimes 	 * we have a valid header (with a link)
7434b88c807SRodney W. Grimes 	 */
7444b88c807SRodney W. Grimes 	return(com_rd(arcn));
7454b88c807SRodney W. Grimes }
7464b88c807SRodney W. Grimes 
7474b88c807SRodney W. Grimes /*
7484b88c807SRodney W. Grimes  * vcpio_endrd()
7494b88c807SRodney W. Grimes  *      no cleanup needed here, just return size of the trailer (for append)
7504b88c807SRodney W. Grimes  * Return:
7514b88c807SRodney W. Grimes  *      size of trailer header in this format
7524b88c807SRodney W. Grimes  */
7534b88c807SRodney W. Grimes 
754778766feSKris Kennaway #ifdef __STDC__
7554b88c807SRodney W. Grimes off_t
7564b88c807SRodney W. Grimes vcpio_endrd(void)
7574b88c807SRodney W. Grimes #else
7584b88c807SRodney W. Grimes off_t
7594b88c807SRodney W. Grimes vcpio_endrd()
7604b88c807SRodney W. Grimes #endif
7614b88c807SRodney W. Grimes {
7624b88c807SRodney W. Grimes 	return((off_t)(sizeof(HD_VCPIO) + sizeof(TRAILER) +
7634b88c807SRodney W. Grimes 		(VCPIO_PAD(sizeof(HD_VCPIO) + sizeof(TRAILER)))));
7644b88c807SRodney W. Grimes }
7654b88c807SRodney W. Grimes 
7664b88c807SRodney W. Grimes /*
7674b88c807SRodney W. Grimes  * crc_stwr()
7684b88c807SRodney W. Grimes  *	start up the device mapping table, enable crc file calculation
7694b88c807SRodney W. Grimes  * Return:
7704b88c807SRodney W. Grimes  *	0 if ok, -1 otherwise (what dev_start() returns)
7714b88c807SRodney W. Grimes  */
7724b88c807SRodney W. Grimes 
773778766feSKris Kennaway #ifdef __STDC__
7744b88c807SRodney W. Grimes int
7754b88c807SRodney W. Grimes crc_stwr(void)
7764b88c807SRodney W. Grimes #else
7774b88c807SRodney W. Grimes int
7784b88c807SRodney W. Grimes crc_stwr()
7794b88c807SRodney W. Grimes #endif
7804b88c807SRodney W. Grimes {
7814b88c807SRodney W. Grimes 	docrc = 1;
7824b88c807SRodney W. Grimes 	return(dev_start());
7834b88c807SRodney W. Grimes }
7844b88c807SRodney W. Grimes 
7854b88c807SRodney W. Grimes /*
7864b88c807SRodney W. Grimes  * vcpio_wr()
7874b88c807SRodney W. Grimes  *	copy the data in the ARCHD to buffer in system VR4 cpio
7884b88c807SRodney W. Grimes  *	(with/without crc) format.
7894b88c807SRodney W. Grimes  * Return
7904b88c807SRodney W. Grimes  *	0 if file has data to be written after the header, 1 if file has
7914b88c807SRodney W. Grimes  *	NO data to write after the header, -1 if archive write failed
7924b88c807SRodney W. Grimes  */
7934b88c807SRodney W. Grimes 
794778766feSKris Kennaway #ifdef __STDC__
7954b88c807SRodney W. Grimes int
7964b88c807SRodney W. Grimes vcpio_wr(register ARCHD *arcn)
7974b88c807SRodney W. Grimes #else
7984b88c807SRodney W. Grimes int
7994b88c807SRodney W. Grimes vcpio_wr(arcn)
8004b88c807SRodney W. Grimes 	register ARCHD *arcn;
8014b88c807SRodney W. Grimes #endif
8024b88c807SRodney W. Grimes {
8034b88c807SRodney W. Grimes 	register HD_VCPIO *hd;
8044b88c807SRodney W. Grimes 	unsigned int nsz;
8054b88c807SRodney W. Grimes 	char hdblk[sizeof(HD_VCPIO)];
8064b88c807SRodney W. Grimes 
8074b88c807SRodney W. Grimes 	/*
8084b88c807SRodney W. Grimes 	 * check and repair truncated device and inode fields in the cpio
8094b88c807SRodney W. Grimes 	 * header
8104b88c807SRodney W. Grimes 	 */
8114b88c807SRodney W. Grimes 	if (map_dev(arcn, (u_long)VCPIO_MASK, (u_long)VCPIO_MASK) < 0)
8124b88c807SRodney W. Grimes 		return(-1);
8134b88c807SRodney W. Grimes 	nsz = arcn->nlen + 1;
8144b88c807SRodney W. Grimes 	hd = (HD_VCPIO *)hdblk;
8154b88c807SRodney W. Grimes 	if ((arcn->type != PAX_BLK) && (arcn->type != PAX_CHR))
8164b88c807SRodney W. Grimes 		arcn->sb.st_rdev = 0;
8174b88c807SRodney W. Grimes 
8184b88c807SRodney W. Grimes 	/*
8194b88c807SRodney W. Grimes 	 * add the proper magic value depending whether we were asked for
8204b88c807SRodney W. Grimes 	 * file data crc's, and the crc if needed.
8214b88c807SRodney W. Grimes 	 */
8224b88c807SRodney W. Grimes 	if (docrc) {
8234b88c807SRodney W. Grimes 		if (ul_asc((u_long)VCMAGIC, hd->c_magic, sizeof(hd->c_magic),
8244b88c807SRodney W. Grimes 	    		OCT) ||
8254b88c807SRodney W. Grimes 		    ul_asc((u_long)arcn->crc,hd->c_chksum,sizeof(hd->c_chksum),
8264b88c807SRodney W. Grimes 	    		HEX))
8274b88c807SRodney W. Grimes 			goto out;
8284b88c807SRodney W. Grimes 	} else {
8294b88c807SRodney W. Grimes 		if (ul_asc((u_long)VMAGIC, hd->c_magic, sizeof(hd->c_magic),
8304b88c807SRodney W. Grimes 	    		OCT) ||
8314b88c807SRodney W. Grimes 		    ul_asc((u_long)0L, hd->c_chksum, sizeof(hd->c_chksum),HEX))
8324b88c807SRodney W. Grimes 			goto out;
8334b88c807SRodney W. Grimes 	}
8344b88c807SRodney W. Grimes 
8354b88c807SRodney W. Grimes 	switch(arcn->type) {
8364b88c807SRodney W. Grimes 	case PAX_CTG:
8374b88c807SRodney W. Grimes 	case PAX_REG:
8384b88c807SRodney W. Grimes 	case PAX_HRG:
8394b88c807SRodney W. Grimes 		/*
8404b88c807SRodney W. Grimes 		 * caller will copy file data to the archive. tell him how
8414b88c807SRodney W. Grimes 		 * much to pad.
8424b88c807SRodney W. Grimes 		 */
8434b88c807SRodney W. Grimes 		arcn->pad = VCPIO_PAD(arcn->sb.st_size);
8444b88c807SRodney W. Grimes #		ifdef NET2_STAT
8454b88c807SRodney W. Grimes 		if (ul_asc((u_long)arcn->sb.st_size, hd->c_filesize,
8464b88c807SRodney W. Grimes 		    sizeof(hd->c_filesize), HEX)) {
8474b88c807SRodney W. Grimes #		else
8484b88c807SRodney W. Grimes 		if (uqd_asc((u_quad_t)arcn->sb.st_size, hd->c_filesize,
8494b88c807SRodney W. Grimes 		    sizeof(hd->c_filesize), HEX)) {
8504b88c807SRodney W. Grimes #		endif
851778766feSKris Kennaway 			paxwarn(1,"File is too large for sv4cpio format %s",
8524b88c807SRodney W. Grimes 			    arcn->org_name);
8534b88c807SRodney W. Grimes 			return(1);
8544b88c807SRodney W. Grimes 		}
8554b88c807SRodney W. Grimes 		break;
8564b88c807SRodney W. Grimes 	case PAX_SLK:
8574b88c807SRodney W. Grimes 		/*
8584b88c807SRodney W. Grimes 		 * no file data for the caller to process, the file data has
8594b88c807SRodney W. Grimes 		 * the size of the link
8604b88c807SRodney W. Grimes 		 */
8614b88c807SRodney W. Grimes 		arcn->pad = 0L;
8624b88c807SRodney W. Grimes 		if (ul_asc((u_long)arcn->ln_nlen, hd->c_filesize,
8634b88c807SRodney W. Grimes 		    sizeof(hd->c_filesize), HEX))
8644b88c807SRodney W. Grimes 			goto out;
8654b88c807SRodney W. Grimes 		break;
8664b88c807SRodney W. Grimes 	default:
8674b88c807SRodney W. Grimes 		/*
8684b88c807SRodney W. Grimes 		 * no file data for the caller to process
8694b88c807SRodney W. Grimes 		 */
8704b88c807SRodney W. Grimes 		arcn->pad = 0L;
8714b88c807SRodney W. Grimes 		if (ul_asc((u_long)0L, hd->c_filesize, sizeof(hd->c_filesize),
8724b88c807SRodney W. Grimes 		    HEX))
8734b88c807SRodney W. Grimes 			goto out;
8744b88c807SRodney W. Grimes 		break;
8754b88c807SRodney W. Grimes 	}
8764b88c807SRodney W. Grimes 
8774b88c807SRodney W. Grimes 	/*
8784b88c807SRodney W. Grimes 	 * set the other fields in the header
8794b88c807SRodney W. Grimes 	 */
8804b88c807SRodney W. Grimes 	if (ul_asc((u_long)arcn->sb.st_ino, hd->c_ino, sizeof(hd->c_ino),
8814b88c807SRodney W. Grimes 		HEX) ||
8824b88c807SRodney W. Grimes 	    ul_asc((u_long)arcn->sb.st_mode, hd->c_mode, sizeof(hd->c_mode),
8834b88c807SRodney W. Grimes 		HEX) ||
8844b88c807SRodney W. Grimes 	    ul_asc((u_long)arcn->sb.st_uid, hd->c_uid, sizeof(hd->c_uid),
8854b88c807SRodney W. Grimes 		HEX) ||
8864b88c807SRodney W. Grimes 	    ul_asc((u_long)arcn->sb.st_gid, hd->c_gid, sizeof(hd->c_gid),
8874b88c807SRodney W. Grimes     		HEX) ||
8884b88c807SRodney W. Grimes 	    ul_asc((u_long)arcn->sb.st_mtime, hd->c_mtime, sizeof(hd->c_mtime),
8894b88c807SRodney W. Grimes     		HEX) ||
8904b88c807SRodney W. Grimes 	    ul_asc((u_long)arcn->sb.st_nlink, hd->c_nlink, sizeof(hd->c_nlink),
8914b88c807SRodney W. Grimes     		HEX) ||
8924b88c807SRodney W. Grimes 	    ul_asc((u_long)MAJOR(arcn->sb.st_dev),hd->c_maj, sizeof(hd->c_maj),
8934b88c807SRodney W. Grimes 		HEX) ||
8944b88c807SRodney W. Grimes 	    ul_asc((u_long)MINOR(arcn->sb.st_dev),hd->c_min, sizeof(hd->c_min),
8954b88c807SRodney W. Grimes 		HEX) ||
8964b88c807SRodney W. Grimes 	    ul_asc((u_long)MAJOR(arcn->sb.st_rdev),hd->c_rmaj,sizeof(hd->c_maj),
8974b88c807SRodney W. Grimes 		HEX) ||
8984b88c807SRodney W. Grimes 	    ul_asc((u_long)MINOR(arcn->sb.st_rdev),hd->c_rmin,sizeof(hd->c_min),
8994b88c807SRodney W. Grimes 		HEX) ||
9004b88c807SRodney W. Grimes 	    ul_asc((u_long)nsz, hd->c_namesize, sizeof(hd->c_namesize), HEX))
9014b88c807SRodney W. Grimes 		goto out;
9024b88c807SRodney W. Grimes 
9034b88c807SRodney W. Grimes 	/*
9044b88c807SRodney W. Grimes 	 * write the header, the file name and padding as required.
9054b88c807SRodney W. Grimes 	 */
9064b88c807SRodney W. Grimes 	if ((wr_rdbuf(hdblk, (int)sizeof(HD_VCPIO)) < 0) ||
9074b88c807SRodney W. Grimes 	    (wr_rdbuf(arcn->name, (int)nsz) < 0)  ||
9084b88c807SRodney W. Grimes 	    (wr_skip((off_t)(VCPIO_PAD(sizeof(HD_VCPIO) + nsz))) < 0)) {
909778766feSKris Kennaway 		paxwarn(1,"Could not write sv4cpio header for %s",arcn->org_name);
9104b88c807SRodney W. Grimes 		return(-1);
9114b88c807SRodney W. Grimes 	}
9124b88c807SRodney W. Grimes 
9134b88c807SRodney W. Grimes 	/*
9144b88c807SRodney W. Grimes 	 * if we have file data, tell the caller we are done, copy the file
9154b88c807SRodney W. Grimes 	 */
9164b88c807SRodney W. Grimes 	if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG) ||
9174b88c807SRodney W. Grimes 	    (arcn->type == PAX_HRG))
9184b88c807SRodney W. Grimes 		return(0);
9194b88c807SRodney W. Grimes 
9204b88c807SRodney W. Grimes 	/*
9214b88c807SRodney W. Grimes 	 * if we are not a link, tell the caller we are done, go to next file
9224b88c807SRodney W. Grimes 	 */
9234b88c807SRodney W. Grimes 	if (arcn->type != PAX_SLK)
9244b88c807SRodney W. Grimes 		return(1);
9254b88c807SRodney W. Grimes 
9264b88c807SRodney W. Grimes 	/*
9274b88c807SRodney W. Grimes 	 * write the link name, tell the caller we are done.
9284b88c807SRodney W. Grimes 	 */
9294b88c807SRodney W. Grimes 	if ((wr_rdbuf(arcn->ln_name, arcn->ln_nlen) < 0) ||
9304b88c807SRodney W. Grimes 	    (wr_skip((off_t)(VCPIO_PAD(arcn->ln_nlen))) < 0)) {
931778766feSKris Kennaway 		paxwarn(1,"Could not write sv4cpio link name for %s",
9324b88c807SRodney W. Grimes 		    arcn->org_name);
9334b88c807SRodney W. Grimes 		return(-1);
9344b88c807SRodney W. Grimes 	}
9354b88c807SRodney W. Grimes 	return(1);
9364b88c807SRodney W. Grimes 
9374b88c807SRodney W. Grimes     out:
9384b88c807SRodney W. Grimes 	/*
9394b88c807SRodney W. Grimes 	 * header field is out of range
9404b88c807SRodney W. Grimes 	 */
941778766feSKris Kennaway 	paxwarn(1,"Sv4cpio header field is too small for file %s",arcn->org_name);
9424b88c807SRodney W. Grimes 	return(1);
9434b88c807SRodney W. Grimes }
9444b88c807SRodney W. Grimes 
9454b88c807SRodney W. Grimes /*
9464b88c807SRodney W. Grimes  * Routines common to the old binary header cpio
9474b88c807SRodney W. Grimes  */
9484b88c807SRodney W. Grimes 
9494b88c807SRodney W. Grimes /*
9504b88c807SRodney W. Grimes  * bcpio_id()
9514b88c807SRodney W. Grimes  *      determine if a block given to us is a old binary cpio header
9524b88c807SRodney W. Grimes  *	(with/without header byte swapping)
9534b88c807SRodney W. Grimes  * Return:
9544b88c807SRodney W. Grimes  *      0 if a valid header, -1 otherwise
9554b88c807SRodney W. Grimes  */
9564b88c807SRodney W. Grimes 
957778766feSKris Kennaway #ifdef __STDC__
9584b88c807SRodney W. Grimes int
9594b88c807SRodney W. Grimes bcpio_id(char *blk, int size)
9604b88c807SRodney W. Grimes #else
9614b88c807SRodney W. Grimes int
9624b88c807SRodney W. Grimes bcpio_id(blk, size)
9634b88c807SRodney W. Grimes 	char *blk;
9644b88c807SRodney W. Grimes 	int size;
9654b88c807SRodney W. Grimes #endif
9664b88c807SRodney W. Grimes {
9674b88c807SRodney W. Grimes 	if (size < sizeof(HD_BCPIO))
9684b88c807SRodney W. Grimes 		return(-1);
9694b88c807SRodney W. Grimes 
9704b88c807SRodney W. Grimes 	/*
9714b88c807SRodney W. Grimes 	 * check both normal and byte swapped magic cookies
9724b88c807SRodney W. Grimes 	 */
9734b88c807SRodney W. Grimes 	if (((u_short)SHRT_EXT(blk)) == MAGIC)
9744b88c807SRodney W. Grimes 		return(0);
9754b88c807SRodney W. Grimes 	if (((u_short)RSHRT_EXT(blk)) == MAGIC) {
9764b88c807SRodney W. Grimes 		if (!swp_head)
9774b88c807SRodney W. Grimes 			++swp_head;
9784b88c807SRodney W. Grimes 		return(0);
9794b88c807SRodney W. Grimes 	}
9804b88c807SRodney W. Grimes 	return(-1);
9814b88c807SRodney W. Grimes }
9824b88c807SRodney W. Grimes 
9834b88c807SRodney W. Grimes /*
9844b88c807SRodney W. Grimes  * bcpio_rd()
9854b88c807SRodney W. Grimes  *	determine if a buffer is a old binary archive entry. (it may have byte
9864b88c807SRodney W. Grimes  *	swapped header) convert and store the values in the ARCHD parameter.
9874b88c807SRodney W. Grimes  *	This is a very old header format and should not really be used.
9884b88c807SRodney W. Grimes  * Return:
9894b88c807SRodney W. Grimes  *	0 if a valid header, -1 otherwise.
9904b88c807SRodney W. Grimes  */
9914b88c807SRodney W. Grimes 
992778766feSKris Kennaway #ifdef __STDC__
9934b88c807SRodney W. Grimes int
9944b88c807SRodney W. Grimes bcpio_rd(register ARCHD *arcn, register char *buf)
9954b88c807SRodney W. Grimes #else
9964b88c807SRodney W. Grimes int
9974b88c807SRodney W. Grimes bcpio_rd(arcn, buf)
9984b88c807SRodney W. Grimes 	register ARCHD *arcn;
9994b88c807SRodney W. Grimes 	register char *buf;
10004b88c807SRodney W. Grimes #endif
10014b88c807SRodney W. Grimes {
10024b88c807SRodney W. Grimes 	register HD_BCPIO *hd;
10034b88c807SRodney W. Grimes 	register int nsz;
10044b88c807SRodney W. Grimes 
10054b88c807SRodney W. Grimes 	/*
10064b88c807SRodney W. Grimes 	 * check the header
10074b88c807SRodney W. Grimes 	 */
10084b88c807SRodney W. Grimes 	if (bcpio_id(buf, sizeof(HD_BCPIO)) < 0)
10094b88c807SRodney W. Grimes 		return(-1);
10104b88c807SRodney W. Grimes 
10114b88c807SRodney W. Grimes 	arcn->pad = 0L;
10124b88c807SRodney W. Grimes 	hd = (HD_BCPIO *)buf;
10134b88c807SRodney W. Grimes 	if (swp_head) {
10144b88c807SRodney W. Grimes 		/*
101546be34b9SKris Kennaway 		 * header has swapped bytes on 16 bit boundaries
10164b88c807SRodney W. Grimes 		 */
10174b88c807SRodney W. Grimes 		arcn->sb.st_dev = (dev_t)(RSHRT_EXT(hd->h_dev));
10184b88c807SRodney W. Grimes 		arcn->sb.st_ino = (ino_t)(RSHRT_EXT(hd->h_ino));
10194b88c807SRodney W. Grimes 		arcn->sb.st_mode = (mode_t)(RSHRT_EXT(hd->h_mode));
10204b88c807SRodney W. Grimes 		arcn->sb.st_uid = (uid_t)(RSHRT_EXT(hd->h_uid));
10214b88c807SRodney W. Grimes 		arcn->sb.st_gid = (gid_t)(RSHRT_EXT(hd->h_gid));
10224b88c807SRodney W. Grimes 		arcn->sb.st_nlink = (nlink_t)(RSHRT_EXT(hd->h_nlink));
10234b88c807SRodney W. Grimes 		arcn->sb.st_rdev = (dev_t)(RSHRT_EXT(hd->h_rdev));
10244b88c807SRodney W. Grimes 		arcn->sb.st_mtime = (time_t)(RSHRT_EXT(hd->h_mtime_1));
10254b88c807SRodney W. Grimes 		arcn->sb.st_mtime =  (arcn->sb.st_mtime << 16) |
10264b88c807SRodney W. Grimes 			((time_t)(RSHRT_EXT(hd->h_mtime_2)));
10274b88c807SRodney W. Grimes 		arcn->sb.st_size = (off_t)(RSHRT_EXT(hd->h_filesize_1));
10284b88c807SRodney W. Grimes 		arcn->sb.st_size = (arcn->sb.st_size << 16) |
10294b88c807SRodney W. Grimes 			((off_t)(RSHRT_EXT(hd->h_filesize_2)));
10304b88c807SRodney W. Grimes 		nsz = (int)(RSHRT_EXT(hd->h_namesize));
10314b88c807SRodney W. Grimes 	} else {
10324b88c807SRodney W. Grimes 		arcn->sb.st_dev = (dev_t)(SHRT_EXT(hd->h_dev));
10334b88c807SRodney W. Grimes 		arcn->sb.st_ino = (ino_t)(SHRT_EXT(hd->h_ino));
10344b88c807SRodney W. Grimes 		arcn->sb.st_mode = (mode_t)(SHRT_EXT(hd->h_mode));
10354b88c807SRodney W. Grimes 		arcn->sb.st_uid = (uid_t)(SHRT_EXT(hd->h_uid));
10364b88c807SRodney W. Grimes 		arcn->sb.st_gid = (gid_t)(SHRT_EXT(hd->h_gid));
10374b88c807SRodney W. Grimes 		arcn->sb.st_nlink = (nlink_t)(SHRT_EXT(hd->h_nlink));
10384b88c807SRodney W. Grimes 		arcn->sb.st_rdev = (dev_t)(SHRT_EXT(hd->h_rdev));
10394b88c807SRodney W. Grimes 		arcn->sb.st_mtime = (time_t)(SHRT_EXT(hd->h_mtime_1));
10404b88c807SRodney W. Grimes 		arcn->sb.st_mtime =  (arcn->sb.st_mtime << 16) |
10414b88c807SRodney W. Grimes 			((time_t)(SHRT_EXT(hd->h_mtime_2)));
10424b88c807SRodney W. Grimes 		arcn->sb.st_size = (off_t)(SHRT_EXT(hd->h_filesize_1));
10434b88c807SRodney W. Grimes 		arcn->sb.st_size = (arcn->sb.st_size << 16) |
10444b88c807SRodney W. Grimes 			((off_t)(SHRT_EXT(hd->h_filesize_2)));
10454b88c807SRodney W. Grimes 		nsz = (int)(SHRT_EXT(hd->h_namesize));
10464b88c807SRodney W. Grimes 	}
10474b88c807SRodney W. Grimes 	arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime;
10484b88c807SRodney W. Grimes 
10494b88c807SRodney W. Grimes 	/*
10504b88c807SRodney W. Grimes 	 * check the file name size, if bogus give up. otherwise read the file
10514b88c807SRodney W. Grimes 	 * name
10524b88c807SRodney W. Grimes 	 */
10534b88c807SRodney W. Grimes 	if (nsz < 2)
10544b88c807SRodney W. Grimes 		return(-1);
10554b88c807SRodney W. Grimes 	arcn->nlen = nsz - 1;
10564b88c807SRodney W. Grimes 	if (rd_nm(arcn, nsz) < 0)
10574b88c807SRodney W. Grimes 		return(-1);
10584b88c807SRodney W. Grimes 
10594b88c807SRodney W. Grimes 	/*
10604b88c807SRodney W. Grimes 	 * header + file name are aligned to 2 byte boundries, skip if needed
10614b88c807SRodney W. Grimes 	 */
10624b88c807SRodney W. Grimes 	if (rd_skip((off_t)(BCPIO_PAD(sizeof(HD_BCPIO) + nsz))) < 0)
10634b88c807SRodney W. Grimes 		return(-1);
10644b88c807SRodney W. Grimes 
10654b88c807SRodney W. Grimes 	/*
10664b88c807SRodney W. Grimes 	 * if not a link (or a file with no data), calculate pad size (for
10674b88c807SRodney W. Grimes 	 * padding which follows the file data), clear the link name and return
10684b88c807SRodney W. Grimes 	 */
10694b88c807SRodney W. Grimes 	if (((arcn->sb.st_mode & C_IFMT) != C_ISLNK)||(arcn->sb.st_size == 0)){
10704b88c807SRodney W. Grimes 		/*
10714b88c807SRodney W. Grimes 		 * we have a valid header (not a link)
10724b88c807SRodney W. Grimes 		 */
10734b88c807SRodney W. Grimes 		arcn->ln_nlen = 0;
10744b88c807SRodney W. Grimes 		arcn->ln_name[0] = '\0';
10754b88c807SRodney W. Grimes 		arcn->pad = BCPIO_PAD(arcn->sb.st_size);
10764b88c807SRodney W. Grimes 		return(com_rd(arcn));
10774b88c807SRodney W. Grimes 	}
10784b88c807SRodney W. Grimes 
10794b88c807SRodney W. Grimes 	if ((rd_ln_nm(arcn) < 0) ||
10804b88c807SRodney W. Grimes 	    (rd_skip((off_t)(BCPIO_PAD(arcn->sb.st_size))) < 0))
10814b88c807SRodney W. Grimes 		return(-1);
10824b88c807SRodney W. Grimes 
10834b88c807SRodney W. Grimes 	/*
10844b88c807SRodney W. Grimes 	 * we have a valid header (with a link)
10854b88c807SRodney W. Grimes 	 */
10864b88c807SRodney W. Grimes 	return(com_rd(arcn));
10874b88c807SRodney W. Grimes }
10884b88c807SRodney W. Grimes 
10894b88c807SRodney W. Grimes /*
10904b88c807SRodney W. Grimes  * bcpio_endrd()
10914b88c807SRodney W. Grimes  *      no cleanup needed here, just return size of the trailer (for append)
10924b88c807SRodney W. Grimes  * Return:
10934b88c807SRodney W. Grimes  *      size of trailer header in this format
10944b88c807SRodney W. Grimes  */
10954b88c807SRodney W. Grimes 
1096778766feSKris Kennaway #ifdef __STDC__
10974b88c807SRodney W. Grimes off_t
10984b88c807SRodney W. Grimes bcpio_endrd(void)
10994b88c807SRodney W. Grimes #else
11004b88c807SRodney W. Grimes off_t
11014b88c807SRodney W. Grimes bcpio_endrd()
11024b88c807SRodney W. Grimes #endif
11034b88c807SRodney W. Grimes {
11044b88c807SRodney W. Grimes 	return((off_t)(sizeof(HD_BCPIO) + sizeof(TRAILER) +
11054b88c807SRodney W. Grimes 		(BCPIO_PAD(sizeof(HD_BCPIO) + sizeof(TRAILER)))));
11064b88c807SRodney W. Grimes }
11074b88c807SRodney W. Grimes 
11084b88c807SRodney W. Grimes /*
11094b88c807SRodney W. Grimes  * bcpio_wr()
11104b88c807SRodney W. Grimes  *	copy the data in the ARCHD to buffer in old binary cpio format
11114b88c807SRodney W. Grimes  *	There is a real chance of field overflow with this critter. So we
11124b88c807SRodney W. Grimes  *	always check the conversion is ok. nobody in his their right mind
11134b88c807SRodney W. Grimes  *	should write an achive in this format...
11144b88c807SRodney W. Grimes  * Return
11154b88c807SRodney W. Grimes  *      0 if file has data to be written after the header, 1 if file has NO
11164b88c807SRodney W. Grimes  *	data to write after the header, -1 if archive write failed
11174b88c807SRodney W. Grimes  */
11184b88c807SRodney W. Grimes 
1119778766feSKris Kennaway #ifdef __STDC__
11204b88c807SRodney W. Grimes int
11214b88c807SRodney W. Grimes bcpio_wr(register ARCHD *arcn)
11224b88c807SRodney W. Grimes #else
11234b88c807SRodney W. Grimes int
11244b88c807SRodney W. Grimes bcpio_wr(arcn)
11254b88c807SRodney W. Grimes 	register ARCHD *arcn;
11264b88c807SRodney W. Grimes #endif
11274b88c807SRodney W. Grimes {
11284b88c807SRodney W. Grimes 	register HD_BCPIO *hd;
11294b88c807SRodney W. Grimes 	register int nsz;
11304b88c807SRodney W. Grimes 	char hdblk[sizeof(HD_BCPIO)];
11314b88c807SRodney W. Grimes 	off_t t_offt;
11324b88c807SRodney W. Grimes 	int t_int;
11334b88c807SRodney W. Grimes 	time_t t_timet;
11344b88c807SRodney W. Grimes 
11354b88c807SRodney W. Grimes 	/*
11364b88c807SRodney W. Grimes 	 * check and repair truncated device and inode fields in the cpio
11374b88c807SRodney W. Grimes 	 * header
11384b88c807SRodney W. Grimes 	 */
11394b88c807SRodney W. Grimes 	if (map_dev(arcn, (u_long)BCPIO_MASK, (u_long)BCPIO_MASK) < 0)
11404b88c807SRodney W. Grimes 		return(-1);
11414b88c807SRodney W. Grimes 
11424b88c807SRodney W. Grimes 	if ((arcn->type != PAX_BLK) && (arcn->type != PAX_CHR))
11434b88c807SRodney W. Grimes 		arcn->sb.st_rdev = 0;
11444b88c807SRodney W. Grimes 	hd = (HD_BCPIO *)hdblk;
11454b88c807SRodney W. Grimes 
11464b88c807SRodney W. Grimes 	switch(arcn->type) {
11474b88c807SRodney W. Grimes 	case PAX_CTG:
11484b88c807SRodney W. Grimes 	case PAX_REG:
11494b88c807SRodney W. Grimes 	case PAX_HRG:
11504b88c807SRodney W. Grimes 		/*
11514b88c807SRodney W. Grimes 		 * caller will copy file data to the archive. tell him how
11524b88c807SRodney W. Grimes 		 * much to pad.
11534b88c807SRodney W. Grimes 		 */
11544b88c807SRodney W. Grimes 		arcn->pad = BCPIO_PAD(arcn->sb.st_size);
11554b88c807SRodney W. Grimes 		hd->h_filesize_1[0] = CHR_WR_0(arcn->sb.st_size);
11564b88c807SRodney W. Grimes 		hd->h_filesize_1[1] = CHR_WR_1(arcn->sb.st_size);
11574b88c807SRodney W. Grimes 		hd->h_filesize_2[0] = CHR_WR_2(arcn->sb.st_size);
11584b88c807SRodney W. Grimes 		hd->h_filesize_2[1] = CHR_WR_3(arcn->sb.st_size);
11594b88c807SRodney W. Grimes 		t_offt = (off_t)(SHRT_EXT(hd->h_filesize_1));
11604b88c807SRodney W. Grimes 		t_offt = (t_offt<<16) | ((off_t)(SHRT_EXT(hd->h_filesize_2)));
11614b88c807SRodney W. Grimes 		if (arcn->sb.st_size != t_offt) {
1162778766feSKris Kennaway 			paxwarn(1,"File is too large for bcpio format %s",
11634b88c807SRodney W. Grimes 			    arcn->org_name);
11644b88c807SRodney W. Grimes 			return(1);
11654b88c807SRodney W. Grimes 		}
11664b88c807SRodney W. Grimes 		break;
11674b88c807SRodney W. Grimes 	case PAX_SLK:
11684b88c807SRodney W. Grimes 		/*
11694b88c807SRodney W. Grimes 		 * no file data for the caller to process, the file data has
11704b88c807SRodney W. Grimes 		 * the size of the link
11714b88c807SRodney W. Grimes 		 */
11724b88c807SRodney W. Grimes 		arcn->pad = 0L;
11734b88c807SRodney W. Grimes 		hd->h_filesize_1[0] = CHR_WR_0(arcn->ln_nlen);
11744b88c807SRodney W. Grimes 		hd->h_filesize_1[1] = CHR_WR_1(arcn->ln_nlen);
11754b88c807SRodney W. Grimes 		hd->h_filesize_2[0] = CHR_WR_2(arcn->ln_nlen);
11764b88c807SRodney W. Grimes 		hd->h_filesize_2[1] = CHR_WR_3(arcn->ln_nlen);
11774b88c807SRodney W. Grimes 		t_int = (int)(SHRT_EXT(hd->h_filesize_1));
11784b88c807SRodney W. Grimes 		t_int = (t_int << 16) | ((int)(SHRT_EXT(hd->h_filesize_2)));
11794b88c807SRodney W. Grimes 		if (arcn->ln_nlen != t_int)
11804b88c807SRodney W. Grimes 			goto out;
11814b88c807SRodney W. Grimes 		break;
11824b88c807SRodney W. Grimes 	default:
11834b88c807SRodney W. Grimes 		/*
11844b88c807SRodney W. Grimes 		 * no file data for the caller to process
11854b88c807SRodney W. Grimes 		 */
11864b88c807SRodney W. Grimes 		arcn->pad = 0L;
11874b88c807SRodney W. Grimes 		hd->h_filesize_1[0] = (char)0;
11884b88c807SRodney W. Grimes 		hd->h_filesize_1[1] = (char)0;
11894b88c807SRodney W. Grimes 		hd->h_filesize_2[0] = (char)0;
11904b88c807SRodney W. Grimes 		hd->h_filesize_2[1] = (char)0;
11914b88c807SRodney W. Grimes 		break;
11924b88c807SRodney W. Grimes 	}
11934b88c807SRodney W. Grimes 
11944b88c807SRodney W. Grimes 	/*
11954b88c807SRodney W. Grimes 	 * build up the rest of the fields
11964b88c807SRodney W. Grimes 	 */
11974b88c807SRodney W. Grimes 	hd->h_magic[0] = CHR_WR_2(MAGIC);
11984b88c807SRodney W. Grimes 	hd->h_magic[1] = CHR_WR_3(MAGIC);
11994b88c807SRodney W. Grimes 	hd->h_dev[0] = CHR_WR_2(arcn->sb.st_dev);
12004b88c807SRodney W. Grimes 	hd->h_dev[1] = CHR_WR_3(arcn->sb.st_dev);
12014b88c807SRodney W. Grimes 	if (arcn->sb.st_dev != (dev_t)(SHRT_EXT(hd->h_dev)))
12024b88c807SRodney W. Grimes 		goto out;
12034b88c807SRodney W. Grimes 	hd->h_ino[0] = CHR_WR_2(arcn->sb.st_ino);
12044b88c807SRodney W. Grimes 	hd->h_ino[1] = CHR_WR_3(arcn->sb.st_ino);
12054b88c807SRodney W. Grimes 	if (arcn->sb.st_ino != (ino_t)(SHRT_EXT(hd->h_ino)))
12064b88c807SRodney W. Grimes 		goto out;
12074b88c807SRodney W. Grimes 	hd->h_mode[0] = CHR_WR_2(arcn->sb.st_mode);
12084b88c807SRodney W. Grimes 	hd->h_mode[1] = CHR_WR_3(arcn->sb.st_mode);
12094b88c807SRodney W. Grimes 	if (arcn->sb.st_mode != (mode_t)(SHRT_EXT(hd->h_mode)))
12104b88c807SRodney W. Grimes 		goto out;
12114b88c807SRodney W. Grimes 	hd->h_uid[0] = CHR_WR_2(arcn->sb.st_uid);
12124b88c807SRodney W. Grimes 	hd->h_uid[1] = CHR_WR_3(arcn->sb.st_uid);
12134b88c807SRodney W. Grimes 	if (arcn->sb.st_uid != (uid_t)(SHRT_EXT(hd->h_uid)))
12144b88c807SRodney W. Grimes 		goto out;
12154b88c807SRodney W. Grimes 	hd->h_gid[0] = CHR_WR_2(arcn->sb.st_gid);
12164b88c807SRodney W. Grimes 	hd->h_gid[1] = CHR_WR_3(arcn->sb.st_gid);
12174b88c807SRodney W. Grimes 	if (arcn->sb.st_gid != (gid_t)(SHRT_EXT(hd->h_gid)))
12184b88c807SRodney W. Grimes 		goto out;
12194b88c807SRodney W. Grimes 	hd->h_nlink[0] = CHR_WR_2(arcn->sb.st_nlink);
12204b88c807SRodney W. Grimes 	hd->h_nlink[1] = CHR_WR_3(arcn->sb.st_nlink);
12214b88c807SRodney W. Grimes 	if (arcn->sb.st_nlink != (nlink_t)(SHRT_EXT(hd->h_nlink)))
12224b88c807SRodney W. Grimes 		goto out;
12234b88c807SRodney W. Grimes 	hd->h_rdev[0] = CHR_WR_2(arcn->sb.st_rdev);
12244b88c807SRodney W. Grimes 	hd->h_rdev[1] = CHR_WR_3(arcn->sb.st_rdev);
12254b88c807SRodney W. Grimes 	if (arcn->sb.st_rdev != (dev_t)(SHRT_EXT(hd->h_rdev)))
12264b88c807SRodney W. Grimes 		goto out;
12274b88c807SRodney W. Grimes 	hd->h_mtime_1[0] = CHR_WR_0(arcn->sb.st_mtime);
12284b88c807SRodney W. Grimes 	hd->h_mtime_1[1] = CHR_WR_1(arcn->sb.st_mtime);
12294b88c807SRodney W. Grimes 	hd->h_mtime_2[0] = CHR_WR_2(arcn->sb.st_mtime);
12304b88c807SRodney W. Grimes 	hd->h_mtime_2[1] = CHR_WR_3(arcn->sb.st_mtime);
12314b88c807SRodney W. Grimes 	t_timet = (time_t)(SHRT_EXT(hd->h_mtime_1));
12324b88c807SRodney W. Grimes 	t_timet =  (t_timet << 16) | ((time_t)(SHRT_EXT(hd->h_mtime_2)));
12334b88c807SRodney W. Grimes 	if (arcn->sb.st_mtime != t_timet)
12344b88c807SRodney W. Grimes 		goto out;
12354b88c807SRodney W. Grimes 	nsz = arcn->nlen + 1;
12364b88c807SRodney W. Grimes 	hd->h_namesize[0] = CHR_WR_2(nsz);
12374b88c807SRodney W. Grimes 	hd->h_namesize[1] = CHR_WR_3(nsz);
12384b88c807SRodney W. Grimes 	if (nsz != (int)(SHRT_EXT(hd->h_namesize)))
12394b88c807SRodney W. Grimes 		goto out;
12404b88c807SRodney W. Grimes 
12414b88c807SRodney W. Grimes 	/*
12424b88c807SRodney W. Grimes 	 * write the header, the file name and padding as required.
12434b88c807SRodney W. Grimes 	 */
12444b88c807SRodney W. Grimes 	if ((wr_rdbuf(hdblk, (int)sizeof(HD_BCPIO)) < 0) ||
12454b88c807SRodney W. Grimes 	    (wr_rdbuf(arcn->name, nsz) < 0) ||
12464b88c807SRodney W. Grimes 	    (wr_skip((off_t)(BCPIO_PAD(sizeof(HD_BCPIO) + nsz))) < 0)) {
1247778766feSKris Kennaway 		paxwarn(1, "Could not write bcpio header for %s", arcn->org_name);
12484b88c807SRodney W. Grimes 		return(-1);
12494b88c807SRodney W. Grimes 	}
12504b88c807SRodney W. Grimes 
12514b88c807SRodney W. Grimes 	/*
12524b88c807SRodney W. Grimes 	 * if we have file data, tell the caller we are done
12534b88c807SRodney W. Grimes 	 */
12544b88c807SRodney W. Grimes 	if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG) ||
12554b88c807SRodney W. Grimes 	    (arcn->type == PAX_HRG))
12564b88c807SRodney W. Grimes 		return(0);
12574b88c807SRodney W. Grimes 
12584b88c807SRodney W. Grimes 	/*
12594b88c807SRodney W. Grimes 	 * if we are not a link, tell the caller we are done, go to next file
12604b88c807SRodney W. Grimes 	 */
12614b88c807SRodney W. Grimes 	if (arcn->type != PAX_SLK)
12624b88c807SRodney W. Grimes 		return(1);
12634b88c807SRodney W. Grimes 
12644b88c807SRodney W. Grimes 	/*
12654b88c807SRodney W. Grimes 	 * write the link name, tell the caller we are done.
12664b88c807SRodney W. Grimes 	 */
12674b88c807SRodney W. Grimes 	if ((wr_rdbuf(arcn->ln_name, arcn->ln_nlen) < 0) ||
12684b88c807SRodney W. Grimes 	    (wr_skip((off_t)(BCPIO_PAD(arcn->ln_nlen))) < 0)) {
1269778766feSKris Kennaway 		paxwarn(1,"Could not write bcpio link name for %s",arcn->org_name);
12704b88c807SRodney W. Grimes 		return(-1);
12714b88c807SRodney W. Grimes 	}
12724b88c807SRodney W. Grimes 	return(1);
12734b88c807SRodney W. Grimes 
12744b88c807SRodney W. Grimes     out:
12754b88c807SRodney W. Grimes 	/*
12764b88c807SRodney W. Grimes 	 * header field is out of range
12774b88c807SRodney W. Grimes 	 */
1278778766feSKris Kennaway 	paxwarn(1,"Bcpio header field is too small for file %s", arcn->org_name);
12794b88c807SRodney W. Grimes 	return(1);
12804b88c807SRodney W. Grimes }
1281