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