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