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