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