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