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