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