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