cpio.c revision 114469
1178825Sdfr/*-
2178825Sdfr * Copyright (c) 1992 Keith Muller.
3178825Sdfr * Copyright (c) 1992, 1993
4178825Sdfr *	The Regents of the University of California.  All rights reserved.
5233294Sstas *
6233294Sstas * This code is derived from software contributed to Berkeley by
7178825Sdfr * Keith Muller of the University of California, San Diego.
8178825Sdfr *
9178825Sdfr * Redistribution and use in source and binary forms, with or without
10178825Sdfr * modification, are permitted provided that the following conditions
11178825Sdfr * are met:
12178825Sdfr * 1. Redistributions of source code must retain the above copyright
13178825Sdfr *    notice, this list of conditions and the following disclaimer.
14178825Sdfr * 2. Redistributions in binary form must reproduce the above copyright
15178825Sdfr *    notice, this list of conditions and the following disclaimer in the
16178825Sdfr *    documentation and/or other materials provided with the distribution.
17178825Sdfr * 3. All advertising materials mentioning features or use of this software
18178825Sdfr *    must display the following acknowledgement:
19178825Sdfr *	This product includes software developed by the University of
20178825Sdfr *	California, Berkeley and its contributors.
21178825Sdfr * 4. Neither the name of the University nor the names of its contributors
22178825Sdfr *    may be used to endorse or promote products derived from this software
23178825Sdfr *    without specific prior written permission.
24178825Sdfr *
25178825Sdfr * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26178825Sdfr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27178825Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28178825Sdfr * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29178825Sdfr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30178825Sdfr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31178825Sdfr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32178825Sdfr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33178825Sdfr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34178825Sdfr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35178825Sdfr * SUCH DAMAGE.
36178825Sdfr */
37178825Sdfr
38178825Sdfr#ifndef lint
39178825Sdfr#if 0
40178825Sdfrstatic char sccsid[] = "@(#)cpio.c	8.1 (Berkeley) 5/31/93";
41178825Sdfr#endif
42178825Sdfr#endif /* not lint */
43178825Sdfr#include <sys/cdefs.h>
44178825Sdfr__FBSDID("$FreeBSD: head/bin/pax/cpio.c 114469 2003-05-02 00:03:10Z obrien $");
45178825Sdfr
46178825Sdfr#include <sys/types.h>
47178825Sdfr#include <sys/time.h>
48178825Sdfr#include <sys/stat.h>
49178825Sdfr#include <string.h>
50178825Sdfr#include <stdint.h>
51178825Sdfr#include <stdio.h>
52178825Sdfr#include <unistd.h>
53178825Sdfr#include <stdlib.h>
54178825Sdfr#include "pax.h"
55178825Sdfr#include "cpio.h"
56178825Sdfr#include "extern.h"
57178825Sdfr
58178825Sdfrstatic int rd_nm(ARCHD *, int);
59178825Sdfrstatic int rd_ln_nm(ARCHD *);
60233294Sstasstatic int com_rd(ARCHD *);
61233294Sstas
62233294Sstas/*
63178825Sdfr * Routines which support the different cpio versions
64178825Sdfr */
65178825Sdfr
66178825Sdfrstatic int swp_head;		/* binary cpio header byte swap */
67178825Sdfr
68178825Sdfr/*
69178825Sdfr * Routines common to all versions of cpio
70178825Sdfr */
71178825Sdfr
72233294Sstas/*
73233294Sstas * cpio_strd()
74233294Sstas *	Fire up the hard link detection code
75233294Sstas * Return:
76233294Sstas *      0 if ok -1 otherwise (the return values of lnk_start())
77233294Sstas */
78178825Sdfr
79178825Sdfrint
80178825Sdfrcpio_strd(void)
81233294Sstas{
82233294Sstas	return(lnk_start());
83233294Sstas}
84178825Sdfr
85178825Sdfr/*
86178825Sdfr * cpio_trail()
87178825Sdfr *	Called to determine if a header block is a valid trailer. We are
88178825Sdfr *	passed the block, the in_sync flag (which tells us we are in resync
89178825Sdfr *	mode; looking for a valid header), and cnt (which starts at zero)
90233294Sstas *	which is used to count the number of empty blocks we have seen so far.
91233294Sstas * Return:
92178825Sdfr *	0 if a valid trailer, -1 if not a valid trailer,
93178825Sdfr */
94178825Sdfr
95178825Sdfrint
96178825Sdfrcpio_trail(ARCHD *arcn)
97233294Sstas{
98178825Sdfr	/*
99178825Sdfr	 * look for trailer id in file we are about to process
100178825Sdfr	 */
101178825Sdfr	if ((strcmp(arcn->name, TRAILER) == 0) && (arcn->sb.st_size == 0))
102178825Sdfr		return(0);
103233294Sstas	return(-1);
104233294Sstas}
105178825Sdfr
106233294Sstas/*
107233294Sstas * com_rd()
108178825Sdfr *	operations common to all cpio read functions.
109233294Sstas * Return:
110233294Sstas *	0
111233294Sstas */
112233294Sstas
113233294Sstasstatic int
114233294Sstascom_rd(ARCHD *arcn)
115233294Sstas{
116233294Sstas	arcn->skip = 0;
117233294Sstas	arcn->pat = NULL;
118233294Sstas	arcn->org_name = arcn->name;
119233294Sstas	switch(arcn->sb.st_mode & C_IFMT) {
120233294Sstas	case C_ISFIFO:
121233294Sstas		arcn->type = PAX_FIF;
122233294Sstas		break;
123178825Sdfr	case C_ISDIR:
124178825Sdfr		arcn->type = PAX_DIR;
125178825Sdfr		break;
126233294Sstas	case C_ISBLK:
127233294Sstas		arcn->type = PAX_BLK;
128233294Sstas		break;
129178825Sdfr	case C_ISCHR:
130178825Sdfr		arcn->type = PAX_CHR;
131178825Sdfr		break;
132178825Sdfr	case C_ISLNK:
133178825Sdfr		arcn->type = PAX_SLK;
134178825Sdfr		break;
135233294Sstas	case C_ISOCK:
136178825Sdfr		arcn->type = PAX_SCK;
137178825Sdfr		break;
138178825Sdfr	case C_ISCTG:
139178825Sdfr	case C_ISREG:
140178825Sdfr	default:
141178825Sdfr		/*
142178825Sdfr		 * we have file data, set up skip (pad is set in the format
143178825Sdfr		 * specific sections)
144178825Sdfr		 */
145178825Sdfr		arcn->sb.st_mode = (arcn->sb.st_mode & 0xfff) | C_ISREG;
146178825Sdfr		arcn->type = PAX_REG;
147178825Sdfr		arcn->skip = arcn->sb.st_size;
148178825Sdfr		break;
149178825Sdfr	}
150178825Sdfr	if (chk_lnk(arcn) < 0)
151178825Sdfr		return(-1);
152178825Sdfr	return(0);
153178825Sdfr}
154178825Sdfr
155178825Sdfr/*
156178825Sdfr * cpio_end_wr()
157178825Sdfr *	write the special file with the name trailer in the proper format
158178825Sdfr * Return:
159178825Sdfr *	result of the write of the trailer from the cpio specific write func
160178825Sdfr */
161178825Sdfr
162178825Sdfrint
163178825Sdfrcpio_endwr(void)
164178825Sdfr{
165178825Sdfr	ARCHD last;
166178825Sdfr
167178825Sdfr	/*
168178825Sdfr	 * create a trailer request and call the proper format write function
169178825Sdfr	 */
170178825Sdfr	memset(&last, 0, sizeof(last));
171178825Sdfr	last.nlen = sizeof(TRAILER) - 1;
172178825Sdfr	last.type = PAX_REG;
173178825Sdfr	last.sb.st_nlink = 1;
174178825Sdfr	(void)strcpy(last.name, TRAILER);
175178825Sdfr	return((*frmt->wr)(&last));
176178825Sdfr}
177178825Sdfr
178178825Sdfr/*
179178825Sdfr * rd_nam()
180178825Sdfr *	read in the file name which follows the cpio header
181178825Sdfr * Return:
182178825Sdfr *	0 if ok, -1 otherwise
183178825Sdfr */
184178825Sdfr
185178825Sdfrstatic int
186178825Sdfrrd_nm(ARCHD *arcn, int nsz)
187178825Sdfr{
188178825Sdfr	/*
189178825Sdfr	 * do not even try bogus values
190178825Sdfr	 */
191178825Sdfr	if ((nsz == 0) || (nsz > (int)sizeof(arcn->name))) {
192178825Sdfr		paxwarn(1, "Cpio file name length %d is out of range", nsz);
193178825Sdfr		return(-1);
194178825Sdfr	}
195178825Sdfr
196178825Sdfr	/*
197178825Sdfr	 * read the name and make sure it is not empty and is \0 terminated
198178825Sdfr	 */
199178825Sdfr	if ((rd_wrbuf(arcn->name,nsz) != nsz) || (arcn->name[nsz-1] != '\0') ||
200178825Sdfr	    (arcn->name[0] == '\0')) {
201178825Sdfr		paxwarn(1, "Cpio file name in header is corrupted");
202		return(-1);
203	}
204	return(0);
205}
206
207/*
208 * rd_ln_nm()
209 *	read in the link name for a file with links. The link name is stored
210 *	like file data (and is NOT \0 terminated!)
211 * Return:
212 *	0 if ok, -1 otherwise
213 */
214
215static int
216rd_ln_nm(ARCHD *arcn)
217{
218	/*
219	 * check the length specified for bogus values
220	 */
221	if ((arcn->sb.st_size == 0) ||
222	    (arcn->sb.st_size >= sizeof(arcn->ln_name))) {
223#		ifdef NET2_STAT
224		paxwarn(1, "Cpio link name length is invalid: %lu",
225		    arcn->sb.st_size);
226#		else
227		paxwarn(1, "Cpio link name length is invalid: %ju",
228		    (uintmax_t)arcn->sb.st_size);
229#		endif
230		return(-1);
231	}
232
233	/*
234	 * read in the link name and \0 terminate it
235	 */
236	if (rd_wrbuf(arcn->ln_name, (int)arcn->sb.st_size) !=
237	    (int)arcn->sb.st_size) {
238		paxwarn(1, "Cpio link name read error");
239		return(-1);
240	}
241	arcn->ln_nlen = arcn->sb.st_size;
242	arcn->ln_name[arcn->ln_nlen] = '\0';
243
244	/*
245	 * watch out for those empty link names
246	 */
247	if (arcn->ln_name[0] == '\0') {
248		paxwarn(1, "Cpio link name is corrupt");
249		return(-1);
250	}
251	return(0);
252}
253
254/*
255 * Routines common to the extended byte oriented cpio format
256 */
257
258/*
259 * cpio_id()
260 *      determine if a block given to us is a valid extended byte oriented
261 *	cpio header
262 * Return:
263 *      0 if a valid header, -1 otherwise
264 */
265
266int
267cpio_id(char *blk, int size)
268{
269	if ((size < (int)sizeof(HD_CPIO)) ||
270	    (strncmp(blk, AMAGIC, sizeof(AMAGIC) - 1) != 0))
271		return(-1);
272	return(0);
273}
274
275/*
276 * cpio_rd()
277 *	determine if a buffer is a byte oriented extended cpio archive entry.
278 *	convert and store the values in the ARCHD parameter.
279 * Return:
280 *	0 if a valid header, -1 otherwise.
281 */
282
283int
284cpio_rd(ARCHD *arcn, char *buf)
285{
286	int nsz;
287	HD_CPIO *hd;
288
289	/*
290	 * check that this is a valid header, if not return -1
291	 */
292	if (cpio_id(buf, sizeof(HD_CPIO)) < 0)
293		return(-1);
294	hd = (HD_CPIO *)buf;
295
296	/*
297	 * byte oriented cpio (posix) does not have padding! extract the octal
298	 * ascii fields from the header
299	 */
300	arcn->pad = 0L;
301	arcn->sb.st_dev = (dev_t)asc_ul(hd->c_dev, sizeof(hd->c_dev), OCT);
302	arcn->sb.st_ino = (ino_t)asc_ul(hd->c_ino, sizeof(hd->c_ino), OCT);
303	arcn->sb.st_mode = (mode_t)asc_ul(hd->c_mode, sizeof(hd->c_mode), OCT);
304	arcn->sb.st_uid = (uid_t)asc_ul(hd->c_uid, sizeof(hd->c_uid), OCT);
305	arcn->sb.st_gid = (gid_t)asc_ul(hd->c_gid, sizeof(hd->c_gid), OCT);
306	arcn->sb.st_nlink = (nlink_t)asc_ul(hd->c_nlink, sizeof(hd->c_nlink),
307	    OCT);
308	arcn->sb.st_rdev = (dev_t)asc_ul(hd->c_rdev, sizeof(hd->c_rdev), OCT);
309#ifdef NET2_STAT
310	arcn->sb.st_mtime = (time_t)asc_ul(hd->c_mtime, sizeof(hd->c_mtime),
311	    OCT);
312#else
313	arcn->sb.st_mtime = (time_t)asc_uqd(hd->c_mtime, sizeof(hd->c_mtime),
314	    OCT);
315#endif
316	arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime;
317#ifdef NET2_STAT
318	arcn->sb.st_size = (off_t)asc_ul(hd->c_filesize,sizeof(hd->c_filesize),
319	    OCT);
320#else
321	arcn->sb.st_size = (off_t)asc_uqd(hd->c_filesize,sizeof(hd->c_filesize),
322	    OCT);
323#endif
324
325	/*
326	 * check name size and if valid, read in the name of this entry (name
327	 * follows header in the archive)
328	 */
329	if ((nsz = (int)asc_ul(hd->c_namesize,sizeof(hd->c_namesize),OCT)) < 2)
330		return(-1);
331	arcn->nlen = nsz - 1;
332	if (rd_nm(arcn, nsz) < 0)
333		return(-1);
334
335	if (((arcn->sb.st_mode&C_IFMT) != C_ISLNK)||(arcn->sb.st_size == 0)) {
336		/*
337	 	 * no link name to read for this file
338	 	 */
339		arcn->ln_nlen = 0;
340		arcn->ln_name[0] = '\0';
341		return(com_rd(arcn));
342	}
343
344	/*
345	 * check link name size and read in the link name. Link names are
346	 * stored like file data.
347	 */
348	if (rd_ln_nm(arcn) < 0)
349		return(-1);
350
351	/*
352	 * we have a valid header (with a link)
353	 */
354	return(com_rd(arcn));
355}
356
357/*
358 * cpio_endrd()
359 *      no cleanup needed here, just return size of the trailer (for append)
360 * Return:
361 *      size of trailer header in this format
362 */
363
364off_t
365cpio_endrd(void)
366{
367	return((off_t)(sizeof(HD_CPIO) + sizeof(TRAILER)));
368}
369
370/*
371 * cpio_stwr()
372 *	start up the device mapping table
373 * Return:
374 *	0 if ok, -1 otherwise (what dev_start() returns)
375 */
376
377int
378cpio_stwr(void)
379{
380	return(dev_start());
381}
382
383/*
384 * cpio_wr()
385 *	copy the data in the ARCHD to buffer in extended byte oriented cpio
386 *	format.
387 * Return
388 *      0 if file has data to be written after the header, 1 if file has NO
389 *	data to write after the header, -1 if archive write failed
390 */
391
392int
393cpio_wr(ARCHD *arcn)
394{
395	HD_CPIO *hd;
396	int nsz;
397	char hdblk[sizeof(HD_CPIO)];
398
399	/*
400	 * check and repair truncated device and inode fields in the header
401	 */
402	if (map_dev(arcn, (u_long)CPIO_MASK, (u_long)CPIO_MASK) < 0)
403		return(-1);
404
405	arcn->pad = 0L;
406	nsz = arcn->nlen + 1;
407	hd = (HD_CPIO *)hdblk;
408	if ((arcn->type != PAX_BLK) && (arcn->type != PAX_CHR))
409		arcn->sb.st_rdev = 0;
410
411	switch(arcn->type) {
412	case PAX_CTG:
413	case PAX_REG:
414	case PAX_HRG:
415		/*
416		 * set data size for file data
417		 */
418#		ifdef NET2_STAT
419		if (ul_asc((u_long)arcn->sb.st_size, hd->c_filesize,
420		    sizeof(hd->c_filesize), OCT)) {
421#		else
422		if (uqd_asc((u_quad_t)arcn->sb.st_size, hd->c_filesize,
423		    sizeof(hd->c_filesize), OCT)) {
424#		endif
425			paxwarn(1,"File is too large for cpio format %s",
426			    arcn->org_name);
427			return(1);
428		}
429		break;
430	case PAX_SLK:
431		/*
432		 * set data size to hold link name
433		 */
434		if (ul_asc((u_long)arcn->ln_nlen, hd->c_filesize,
435		    sizeof(hd->c_filesize), OCT))
436			goto out;
437		break;
438	default:
439		/*
440		 * all other file types have no file data
441		 */
442		if (ul_asc((u_long)0, hd->c_filesize, sizeof(hd->c_filesize),
443		     OCT))
444			goto out;
445		break;
446	}
447
448	/*
449	 * copy the values to the header using octal ascii
450	 */
451	if (ul_asc((u_long)MAGIC, hd->c_magic, sizeof(hd->c_magic), OCT) ||
452	    ul_asc((u_long)arcn->sb.st_dev, hd->c_dev, sizeof(hd->c_dev),
453		OCT) ||
454	    ul_asc((u_long)arcn->sb.st_ino, hd->c_ino, sizeof(hd->c_ino),
455		OCT) ||
456	    ul_asc((u_long)arcn->sb.st_mode, hd->c_mode, sizeof(hd->c_mode),
457		OCT) ||
458	    ul_asc((u_long)arcn->sb.st_uid, hd->c_uid, sizeof(hd->c_uid),
459		OCT) ||
460	    ul_asc((u_long)arcn->sb.st_gid, hd->c_gid, sizeof(hd->c_gid),
461		OCT) ||
462	    ul_asc((u_long)arcn->sb.st_nlink, hd->c_nlink, sizeof(hd->c_nlink),
463		 OCT) ||
464	    ul_asc((u_long)arcn->sb.st_rdev, hd->c_rdev, sizeof(hd->c_rdev),
465		OCT) ||
466	    ul_asc((u_long)arcn->sb.st_mtime,hd->c_mtime,sizeof(hd->c_mtime),
467		OCT) ||
468	    ul_asc((u_long)nsz, hd->c_namesize, sizeof(hd->c_namesize), OCT))
469		goto out;
470
471	/*
472	 * write the file name to the archive
473	 */
474	if ((wr_rdbuf(hdblk, (int)sizeof(HD_CPIO)) < 0) ||
475	    (wr_rdbuf(arcn->name, nsz) < 0)) {
476		paxwarn(1, "Unable to write cpio header for %s", arcn->org_name);
477		return(-1);
478	}
479
480	/*
481	 * if this file has data, we are done. The caller will write the file
482	 * data, if we are link tell caller we are done, go to next file
483	 */
484	if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG) ||
485	    (arcn->type == PAX_HRG))
486		return(0);
487	if (arcn->type != PAX_SLK)
488		return(1);
489
490	/*
491	 * write the link name to the archive, tell the caller to go to the
492	 * next file as we are done.
493	 */
494	if (wr_rdbuf(arcn->ln_name, arcn->ln_nlen) < 0) {
495		paxwarn(1,"Unable to write cpio link name for %s",arcn->org_name);
496		return(-1);
497	}
498	return(1);
499
500    out:
501	/*
502	 * header field is out of range
503	 */
504	paxwarn(1, "Cpio header field is too small to store file %s",
505	    arcn->org_name);
506	return(1);
507}
508
509/*
510 * Routines common to the system VR4 version of cpio (with/without file CRC)
511 */
512
513/*
514 * vcpio_id()
515 *      determine if a block given to us is a valid system VR4 cpio header
516 *	WITHOUT crc. WATCH it the magic cookies are in OCTAL, the header
517 *	uses HEX
518 * Return:
519 *      0 if a valid header, -1 otherwise
520 */
521
522int
523vcpio_id(char *blk, int size)
524{
525	if ((size < (int)sizeof(HD_VCPIO)) ||
526	    (strncmp(blk, AVMAGIC, sizeof(AVMAGIC) - 1) != 0))
527		return(-1);
528	return(0);
529}
530
531/*
532 * crc_id()
533 *      determine if a block given to us is a valid system VR4 cpio header
534 *	WITH crc. WATCH it the magic cookies are in OCTAL the header uses HEX
535 * Return:
536 *      0 if a valid header, -1 otherwise
537 */
538
539int
540crc_id(char *blk, int size)
541{
542	if ((size < (int)sizeof(HD_VCPIO)) ||
543	    (strncmp(blk, AVCMAGIC, (int)sizeof(AVCMAGIC) - 1) != 0))
544		return(-1);
545	return(0);
546}
547
548/*
549 * crc_strd()
550 w	set file data CRC calculations. Fire up the hard link detection code
551 * Return:
552 *      0 if ok -1 otherwise (the return values of lnk_start())
553 */
554
555int
556crc_strd(void)
557{
558	docrc = 1;
559	return(lnk_start());
560}
561
562/*
563 * vcpio_rd()
564 *	determine if a buffer is a system VR4 archive entry. (with/without CRC)
565 *	convert and store the values in the ARCHD parameter.
566 * Return:
567 *	0 if a valid header, -1 otherwise.
568 */
569
570int
571vcpio_rd(ARCHD *arcn, char *buf)
572{
573	HD_VCPIO *hd;
574	dev_t devminor;
575	dev_t devmajor;
576	int nsz;
577
578	/*
579	 * during the id phase it was determined if we were using CRC, use the
580	 * proper id routine.
581	 */
582	if (docrc) {
583		if (crc_id(buf, sizeof(HD_VCPIO)) < 0)
584			return(-1);
585	} else {
586		if (vcpio_id(buf, sizeof(HD_VCPIO)) < 0)
587			return(-1);
588	}
589
590	hd = (HD_VCPIO *)buf;
591	arcn->pad = 0L;
592
593	/*
594	 * extract the hex ascii fields from the header
595	 */
596	arcn->sb.st_ino = (ino_t)asc_ul(hd->c_ino, sizeof(hd->c_ino), HEX);
597	arcn->sb.st_mode = (mode_t)asc_ul(hd->c_mode, sizeof(hd->c_mode), HEX);
598	arcn->sb.st_uid = (uid_t)asc_ul(hd->c_uid, sizeof(hd->c_uid), HEX);
599	arcn->sb.st_gid = (gid_t)asc_ul(hd->c_gid, sizeof(hd->c_gid), HEX);
600#ifdef NET2_STAT
601	arcn->sb.st_mtime = (time_t)asc_ul(hd->c_mtime,sizeof(hd->c_mtime),HEX);
602#else
603	arcn->sb.st_mtime = (time_t)asc_uqd(hd->c_mtime,sizeof(hd->c_mtime),HEX);
604#endif
605	arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime;
606#ifdef NET2_STAT
607	arcn->sb.st_size = (off_t)asc_ul(hd->c_filesize,
608	    sizeof(hd->c_filesize), HEX);
609#else
610	arcn->sb.st_size = (off_t)asc_uqd(hd->c_filesize,
611	    sizeof(hd->c_filesize), HEX);
612#endif
613	arcn->sb.st_nlink = (nlink_t)asc_ul(hd->c_nlink, sizeof(hd->c_nlink),
614	    HEX);
615	devmajor = (dev_t)asc_ul(hd->c_maj, sizeof(hd->c_maj), HEX);
616	devminor = (dev_t)asc_ul(hd->c_min, sizeof(hd->c_min), HEX);
617	arcn->sb.st_dev = TODEV(devmajor, devminor);
618	devmajor = (dev_t)asc_ul(hd->c_rmaj, sizeof(hd->c_maj), HEX);
619	devminor = (dev_t)asc_ul(hd->c_rmin, sizeof(hd->c_min), HEX);
620	arcn->sb.st_rdev = TODEV(devmajor, devminor);
621	arcn->crc = asc_ul(hd->c_chksum, sizeof(hd->c_chksum), HEX);
622
623	/*
624	 * check the length of the file name, if ok read it in, return -1 if
625	 * bogus
626	 */
627	if ((nsz = (int)asc_ul(hd->c_namesize,sizeof(hd->c_namesize),HEX)) < 2)
628		return(-1);
629	arcn->nlen = nsz - 1;
630	if (rd_nm(arcn, nsz) < 0)
631		return(-1);
632
633	/*
634	 * skip padding. header + filename is aligned to 4 byte boundries
635	 */
636	if (rd_skip((off_t)(VCPIO_PAD(sizeof(HD_VCPIO) + nsz))) < 0)
637		return(-1);
638
639	/*
640	 * if not a link (or a file with no data), calculate pad size (for
641	 * padding which follows the file data), clear the link name and return
642	 */
643	if (((arcn->sb.st_mode&C_IFMT) != C_ISLNK)||(arcn->sb.st_size == 0)) {
644		/*
645		 * we have a valid header (not a link)
646		 */
647		arcn->ln_nlen = 0;
648		arcn->ln_name[0] = '\0';
649		arcn->pad = VCPIO_PAD(arcn->sb.st_size);
650		return(com_rd(arcn));
651	}
652
653	/*
654	 * read in the link name and skip over the padding
655	 */
656	if ((rd_ln_nm(arcn) < 0) ||
657	    (rd_skip((off_t)(VCPIO_PAD(arcn->sb.st_size))) < 0))
658		return(-1);
659
660	/*
661	 * we have a valid header (with a link)
662	 */
663	return(com_rd(arcn));
664}
665
666/*
667 * vcpio_endrd()
668 *      no cleanup needed here, just return size of the trailer (for append)
669 * Return:
670 *      size of trailer header in this format
671 */
672
673off_t
674vcpio_endrd(void)
675{
676	return((off_t)(sizeof(HD_VCPIO) + sizeof(TRAILER) +
677		(VCPIO_PAD(sizeof(HD_VCPIO) + sizeof(TRAILER)))));
678}
679
680/*
681 * crc_stwr()
682 *	start up the device mapping table, enable crc file calculation
683 * Return:
684 *	0 if ok, -1 otherwise (what dev_start() returns)
685 */
686
687int
688crc_stwr(void)
689{
690	docrc = 1;
691	return(dev_start());
692}
693
694/*
695 * vcpio_wr()
696 *	copy the data in the ARCHD to buffer in system VR4 cpio
697 *	(with/without crc) format.
698 * Return
699 *	0 if file has data to be written after the header, 1 if file has
700 *	NO data to write after the header, -1 if archive write failed
701 */
702
703int
704vcpio_wr(ARCHD *arcn)
705{
706	HD_VCPIO *hd;
707	unsigned int nsz;
708	char hdblk[sizeof(HD_VCPIO)];
709
710	/*
711	 * check and repair truncated device and inode fields in the cpio
712	 * header
713	 */
714	if (map_dev(arcn, (u_long)VCPIO_MASK, (u_long)VCPIO_MASK) < 0)
715		return(-1);
716	nsz = arcn->nlen + 1;
717	hd = (HD_VCPIO *)hdblk;
718	if ((arcn->type != PAX_BLK) && (arcn->type != PAX_CHR))
719		arcn->sb.st_rdev = 0;
720
721	/*
722	 * add the proper magic value depending whether we were asked for
723	 * file data crc's, and the crc if needed.
724	 */
725	if (docrc) {
726		if (ul_asc((u_long)VCMAGIC, hd->c_magic, sizeof(hd->c_magic),
727	    		OCT) ||
728		    ul_asc((u_long)arcn->crc,hd->c_chksum,sizeof(hd->c_chksum),
729	    		HEX))
730			goto out;
731	} else {
732		if (ul_asc((u_long)VMAGIC, hd->c_magic, sizeof(hd->c_magic),
733	    		OCT) ||
734		    ul_asc((u_long)0L, hd->c_chksum, sizeof(hd->c_chksum),HEX))
735			goto out;
736	}
737
738	switch(arcn->type) {
739	case PAX_CTG:
740	case PAX_REG:
741	case PAX_HRG:
742		/*
743		 * caller will copy file data to the archive. tell him how
744		 * much to pad.
745		 */
746		arcn->pad = VCPIO_PAD(arcn->sb.st_size);
747#		ifdef NET2_STAT
748		if (ul_asc((u_long)arcn->sb.st_size, hd->c_filesize,
749		    sizeof(hd->c_filesize), HEX)) {
750#		else
751		if (uqd_asc((u_quad_t)arcn->sb.st_size, hd->c_filesize,
752		    sizeof(hd->c_filesize), HEX)) {
753#		endif
754			paxwarn(1,"File is too large for sv4cpio format %s",
755			    arcn->org_name);
756			return(1);
757		}
758		break;
759	case PAX_SLK:
760		/*
761		 * no file data for the caller to process, the file data has
762		 * the size of the link
763		 */
764		arcn->pad = 0L;
765		if (ul_asc((u_long)arcn->ln_nlen, hd->c_filesize,
766		    sizeof(hd->c_filesize), HEX))
767			goto out;
768		break;
769	default:
770		/*
771		 * no file data for the caller to process
772		 */
773		arcn->pad = 0L;
774		if (ul_asc((u_long)0L, hd->c_filesize, sizeof(hd->c_filesize),
775		    HEX))
776			goto out;
777		break;
778	}
779
780	/*
781	 * set the other fields in the header
782	 */
783	if (ul_asc((u_long)arcn->sb.st_ino, hd->c_ino, sizeof(hd->c_ino),
784		HEX) ||
785	    ul_asc((u_long)arcn->sb.st_mode, hd->c_mode, sizeof(hd->c_mode),
786		HEX) ||
787	    ul_asc((u_long)arcn->sb.st_uid, hd->c_uid, sizeof(hd->c_uid),
788		HEX) ||
789	    ul_asc((u_long)arcn->sb.st_gid, hd->c_gid, sizeof(hd->c_gid),
790    		HEX) ||
791	    ul_asc((u_long)arcn->sb.st_mtime, hd->c_mtime, sizeof(hd->c_mtime),
792    		HEX) ||
793	    ul_asc((u_long)arcn->sb.st_nlink, hd->c_nlink, sizeof(hd->c_nlink),
794    		HEX) ||
795	    ul_asc((u_long)MAJOR(arcn->sb.st_dev),hd->c_maj, sizeof(hd->c_maj),
796		HEX) ||
797	    ul_asc((u_long)MINOR(arcn->sb.st_dev),hd->c_min, sizeof(hd->c_min),
798		HEX) ||
799	    ul_asc((u_long)MAJOR(arcn->sb.st_rdev),hd->c_rmaj,sizeof(hd->c_maj),
800		HEX) ||
801	    ul_asc((u_long)MINOR(arcn->sb.st_rdev),hd->c_rmin,sizeof(hd->c_min),
802		HEX) ||
803	    ul_asc((u_long)nsz, hd->c_namesize, sizeof(hd->c_namesize), HEX))
804		goto out;
805
806	/*
807	 * write the header, the file name and padding as required.
808	 */
809	if ((wr_rdbuf(hdblk, (int)sizeof(HD_VCPIO)) < 0) ||
810	    (wr_rdbuf(arcn->name, (int)nsz) < 0)  ||
811	    (wr_skip((off_t)(VCPIO_PAD(sizeof(HD_VCPIO) + nsz))) < 0)) {
812		paxwarn(1,"Could not write sv4cpio header for %s",arcn->org_name);
813		return(-1);
814	}
815
816	/*
817	 * if we have file data, tell the caller we are done, copy the file
818	 */
819	if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG) ||
820	    (arcn->type == PAX_HRG))
821		return(0);
822
823	/*
824	 * if we are not a link, tell the caller we are done, go to next file
825	 */
826	if (arcn->type != PAX_SLK)
827		return(1);
828
829	/*
830	 * write the link name, tell the caller we are done.
831	 */
832	if ((wr_rdbuf(arcn->ln_name, arcn->ln_nlen) < 0) ||
833	    (wr_skip((off_t)(VCPIO_PAD(arcn->ln_nlen))) < 0)) {
834		paxwarn(1,"Could not write sv4cpio link name for %s",
835		    arcn->org_name);
836		return(-1);
837	}
838	return(1);
839
840    out:
841	/*
842	 * header field is out of range
843	 */
844	paxwarn(1,"Sv4cpio header field is too small for file %s",arcn->org_name);
845	return(1);
846}
847
848/*
849 * Routines common to the old binary header cpio
850 */
851
852/*
853 * bcpio_id()
854 *      determine if a block given to us is an old binary cpio header
855 *	(with/without header byte swapping)
856 * Return:
857 *      0 if a valid header, -1 otherwise
858 */
859
860int
861bcpio_id(char *blk, int size)
862{
863	if (size < (int)sizeof(HD_BCPIO))
864		return(-1);
865
866	/*
867	 * check both normal and byte swapped magic cookies
868	 */
869	if (((u_short)SHRT_EXT(blk)) == MAGIC)
870		return(0);
871	if (((u_short)RSHRT_EXT(blk)) == MAGIC) {
872		if (!swp_head)
873			++swp_head;
874		return(0);
875	}
876	return(-1);
877}
878
879/*
880 * bcpio_rd()
881 *	determine if a buffer is an old binary archive entry. (It may have byte
882 *	swapped header) convert and store the values in the ARCHD parameter.
883 *	This is a very old header format and should not really be used.
884 * Return:
885 *	0 if a valid header, -1 otherwise.
886 */
887
888int
889bcpio_rd(ARCHD *arcn, char *buf)
890{
891	HD_BCPIO *hd;
892	int nsz;
893
894	/*
895	 * check the header
896	 */
897	if (bcpio_id(buf, sizeof(HD_BCPIO)) < 0)
898		return(-1);
899
900	arcn->pad = 0L;
901	hd = (HD_BCPIO *)buf;
902	if (swp_head) {
903		/*
904		 * header has swapped bytes on 16 bit boundaries
905		 */
906		arcn->sb.st_dev = (dev_t)(RSHRT_EXT(hd->h_dev));
907		arcn->sb.st_ino = (ino_t)(RSHRT_EXT(hd->h_ino));
908		arcn->sb.st_mode = (mode_t)(RSHRT_EXT(hd->h_mode));
909		arcn->sb.st_uid = (uid_t)(RSHRT_EXT(hd->h_uid));
910		arcn->sb.st_gid = (gid_t)(RSHRT_EXT(hd->h_gid));
911		arcn->sb.st_nlink = (nlink_t)(RSHRT_EXT(hd->h_nlink));
912		arcn->sb.st_rdev = (dev_t)(RSHRT_EXT(hd->h_rdev));
913		arcn->sb.st_mtime = (time_t)(RSHRT_EXT(hd->h_mtime_1));
914		arcn->sb.st_mtime =  (arcn->sb.st_mtime << 16) |
915			((time_t)(RSHRT_EXT(hd->h_mtime_2)));
916		arcn->sb.st_size = (off_t)(RSHRT_EXT(hd->h_filesize_1));
917		arcn->sb.st_size = (arcn->sb.st_size << 16) |
918			((off_t)(RSHRT_EXT(hd->h_filesize_2)));
919		nsz = (int)(RSHRT_EXT(hd->h_namesize));
920	} else {
921		arcn->sb.st_dev = (dev_t)(SHRT_EXT(hd->h_dev));
922		arcn->sb.st_ino = (ino_t)(SHRT_EXT(hd->h_ino));
923		arcn->sb.st_mode = (mode_t)(SHRT_EXT(hd->h_mode));
924		arcn->sb.st_uid = (uid_t)(SHRT_EXT(hd->h_uid));
925		arcn->sb.st_gid = (gid_t)(SHRT_EXT(hd->h_gid));
926		arcn->sb.st_nlink = (nlink_t)(SHRT_EXT(hd->h_nlink));
927		arcn->sb.st_rdev = (dev_t)(SHRT_EXT(hd->h_rdev));
928		arcn->sb.st_mtime = (time_t)(SHRT_EXT(hd->h_mtime_1));
929		arcn->sb.st_mtime =  (arcn->sb.st_mtime << 16) |
930			((time_t)(SHRT_EXT(hd->h_mtime_2)));
931		arcn->sb.st_size = (off_t)(SHRT_EXT(hd->h_filesize_1));
932		arcn->sb.st_size = (arcn->sb.st_size << 16) |
933			((off_t)(SHRT_EXT(hd->h_filesize_2)));
934		nsz = (int)(SHRT_EXT(hd->h_namesize));
935	}
936	arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime;
937
938	/*
939	 * check the file name size, if bogus give up. otherwise read the file
940	 * name
941	 */
942	if (nsz < 2)
943		return(-1);
944	arcn->nlen = nsz - 1;
945	if (rd_nm(arcn, nsz) < 0)
946		return(-1);
947
948	/*
949	 * header + file name are aligned to 2 byte boundries, skip if needed
950	 */
951	if (rd_skip((off_t)(BCPIO_PAD(sizeof(HD_BCPIO) + nsz))) < 0)
952		return(-1);
953
954	/*
955	 * if not a link (or a file with no data), calculate pad size (for
956	 * padding which follows the file data), clear the link name and return
957	 */
958	if (((arcn->sb.st_mode & C_IFMT) != C_ISLNK)||(arcn->sb.st_size == 0)){
959		/*
960		 * we have a valid header (not a link)
961		 */
962		arcn->ln_nlen = 0;
963		arcn->ln_name[0] = '\0';
964		arcn->pad = BCPIO_PAD(arcn->sb.st_size);
965		return(com_rd(arcn));
966	}
967
968	if ((rd_ln_nm(arcn) < 0) ||
969	    (rd_skip((off_t)(BCPIO_PAD(arcn->sb.st_size))) < 0))
970		return(-1);
971
972	/*
973	 * we have a valid header (with a link)
974	 */
975	return(com_rd(arcn));
976}
977
978/*
979 * bcpio_endrd()
980 *      no cleanup needed here, just return size of the trailer (for append)
981 * Return:
982 *      size of trailer header in this format
983 */
984
985off_t
986bcpio_endrd(void)
987{
988	return((off_t)(sizeof(HD_BCPIO) + sizeof(TRAILER) +
989		(BCPIO_PAD(sizeof(HD_BCPIO) + sizeof(TRAILER)))));
990}
991
992/*
993 * bcpio_wr()
994 *	copy the data in the ARCHD to buffer in old binary cpio format
995 *	There is a real chance of field overflow with this critter. So we
996 *	always check the conversion is ok. nobody in his their right mind
997 *	should write an achive in this format...
998 * Return
999 *      0 if file has data to be written after the header, 1 if file has NO
1000 *	data to write after the header, -1 if archive write failed
1001 */
1002
1003int
1004bcpio_wr(ARCHD *arcn)
1005{
1006	HD_BCPIO *hd;
1007	int nsz;
1008	char hdblk[sizeof(HD_BCPIO)];
1009	off_t t_offt;
1010	int t_int;
1011	time_t t_timet;
1012
1013	/*
1014	 * check and repair truncated device and inode fields in the cpio
1015	 * header
1016	 */
1017	if (map_dev(arcn, (u_long)BCPIO_MASK, (u_long)BCPIO_MASK) < 0)
1018		return(-1);
1019
1020	if ((arcn->type != PAX_BLK) && (arcn->type != PAX_CHR))
1021		arcn->sb.st_rdev = 0;
1022	hd = (HD_BCPIO *)hdblk;
1023
1024	switch(arcn->type) {
1025	case PAX_CTG:
1026	case PAX_REG:
1027	case PAX_HRG:
1028		/*
1029		 * caller will copy file data to the archive. tell him how
1030		 * much to pad.
1031		 */
1032		arcn->pad = BCPIO_PAD(arcn->sb.st_size);
1033		hd->h_filesize_1[0] = CHR_WR_0(arcn->sb.st_size);
1034		hd->h_filesize_1[1] = CHR_WR_1(arcn->sb.st_size);
1035		hd->h_filesize_2[0] = CHR_WR_2(arcn->sb.st_size);
1036		hd->h_filesize_2[1] = CHR_WR_3(arcn->sb.st_size);
1037		t_offt = (off_t)(SHRT_EXT(hd->h_filesize_1));
1038		t_offt = (t_offt<<16) | ((off_t)(SHRT_EXT(hd->h_filesize_2)));
1039		if (arcn->sb.st_size != t_offt) {
1040			paxwarn(1,"File is too large for bcpio format %s",
1041			    arcn->org_name);
1042			return(1);
1043		}
1044		break;
1045	case PAX_SLK:
1046		/*
1047		 * no file data for the caller to process, the file data has
1048		 * the size of the link
1049		 */
1050		arcn->pad = 0L;
1051		hd->h_filesize_1[0] = CHR_WR_0(arcn->ln_nlen);
1052		hd->h_filesize_1[1] = CHR_WR_1(arcn->ln_nlen);
1053		hd->h_filesize_2[0] = CHR_WR_2(arcn->ln_nlen);
1054		hd->h_filesize_2[1] = CHR_WR_3(arcn->ln_nlen);
1055		t_int = (int)(SHRT_EXT(hd->h_filesize_1));
1056		t_int = (t_int << 16) | ((int)(SHRT_EXT(hd->h_filesize_2)));
1057		if (arcn->ln_nlen != t_int)
1058			goto out;
1059		break;
1060	default:
1061		/*
1062		 * no file data for the caller to process
1063		 */
1064		arcn->pad = 0L;
1065		hd->h_filesize_1[0] = (char)0;
1066		hd->h_filesize_1[1] = (char)0;
1067		hd->h_filesize_2[0] = (char)0;
1068		hd->h_filesize_2[1] = (char)0;
1069		break;
1070	}
1071
1072	/*
1073	 * build up the rest of the fields
1074	 */
1075	hd->h_magic[0] = CHR_WR_2(MAGIC);
1076	hd->h_magic[1] = CHR_WR_3(MAGIC);
1077	hd->h_dev[0] = CHR_WR_2(arcn->sb.st_dev);
1078	hd->h_dev[1] = CHR_WR_3(arcn->sb.st_dev);
1079	if (arcn->sb.st_dev != (dev_t)(SHRT_EXT(hd->h_dev)))
1080		goto out;
1081	hd->h_ino[0] = CHR_WR_2(arcn->sb.st_ino);
1082	hd->h_ino[1] = CHR_WR_3(arcn->sb.st_ino);
1083	if (arcn->sb.st_ino != (ino_t)(SHRT_EXT(hd->h_ino)))
1084		goto out;
1085	hd->h_mode[0] = CHR_WR_2(arcn->sb.st_mode);
1086	hd->h_mode[1] = CHR_WR_3(arcn->sb.st_mode);
1087	if (arcn->sb.st_mode != (mode_t)(SHRT_EXT(hd->h_mode)))
1088		goto out;
1089	hd->h_uid[0] = CHR_WR_2(arcn->sb.st_uid);
1090	hd->h_uid[1] = CHR_WR_3(arcn->sb.st_uid);
1091	if (arcn->sb.st_uid != (uid_t)(SHRT_EXT(hd->h_uid)))
1092		goto out;
1093	hd->h_gid[0] = CHR_WR_2(arcn->sb.st_gid);
1094	hd->h_gid[1] = CHR_WR_3(arcn->sb.st_gid);
1095	if (arcn->sb.st_gid != (gid_t)(SHRT_EXT(hd->h_gid)))
1096		goto out;
1097	hd->h_nlink[0] = CHR_WR_2(arcn->sb.st_nlink);
1098	hd->h_nlink[1] = CHR_WR_3(arcn->sb.st_nlink);
1099	if (arcn->sb.st_nlink != (nlink_t)(SHRT_EXT(hd->h_nlink)))
1100		goto out;
1101	hd->h_rdev[0] = CHR_WR_2(arcn->sb.st_rdev);
1102	hd->h_rdev[1] = CHR_WR_3(arcn->sb.st_rdev);
1103	if (arcn->sb.st_rdev != (dev_t)(SHRT_EXT(hd->h_rdev)))
1104		goto out;
1105	hd->h_mtime_1[0] = CHR_WR_0(arcn->sb.st_mtime);
1106	hd->h_mtime_1[1] = CHR_WR_1(arcn->sb.st_mtime);
1107	hd->h_mtime_2[0] = CHR_WR_2(arcn->sb.st_mtime);
1108	hd->h_mtime_2[1] = CHR_WR_3(arcn->sb.st_mtime);
1109	t_timet = (time_t)(SHRT_EXT(hd->h_mtime_1));
1110	t_timet =  (t_timet << 16) | ((time_t)(SHRT_EXT(hd->h_mtime_2)));
1111	if (arcn->sb.st_mtime != t_timet)
1112		goto out;
1113	nsz = arcn->nlen + 1;
1114	hd->h_namesize[0] = CHR_WR_2(nsz);
1115	hd->h_namesize[1] = CHR_WR_3(nsz);
1116	if (nsz != (int)(SHRT_EXT(hd->h_namesize)))
1117		goto out;
1118
1119	/*
1120	 * write the header, the file name and padding as required.
1121	 */
1122	if ((wr_rdbuf(hdblk, (int)sizeof(HD_BCPIO)) < 0) ||
1123	    (wr_rdbuf(arcn->name, nsz) < 0) ||
1124	    (wr_skip((off_t)(BCPIO_PAD(sizeof(HD_BCPIO) + nsz))) < 0)) {
1125		paxwarn(1, "Could not write bcpio header for %s", arcn->org_name);
1126		return(-1);
1127	}
1128
1129	/*
1130	 * if we have file data, tell the caller we are done
1131	 */
1132	if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG) ||
1133	    (arcn->type == PAX_HRG))
1134		return(0);
1135
1136	/*
1137	 * if we are not a link, tell the caller we are done, go to next file
1138	 */
1139	if (arcn->type != PAX_SLK)
1140		return(1);
1141
1142	/*
1143	 * write the link name, tell the caller we are done.
1144	 */
1145	if ((wr_rdbuf(arcn->ln_name, arcn->ln_nlen) < 0) ||
1146	    (wr_skip((off_t)(BCPIO_PAD(arcn->ln_nlen))) < 0)) {
1147		paxwarn(1,"Could not write bcpio link name for %s",arcn->org_name);
1148		return(-1);
1149	}
1150	return(1);
1151
1152    out:
1153	/*
1154	 * header field is out of range
1155	 */
1156	paxwarn(1,"Bcpio header field is too small for file %s", arcn->org_name);
1157	return(1);
1158}
1159