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