1 /* $OpenBSD: cpio.c,v 1.5 1997/07/25 18:58:28 mickey Exp $ */
2 /* $NetBSD: cpio.c,v 1.5 1995/03/21 09:07:13 cgd Exp $ */
5 * Copyright (c) 1992 Keith Muller.
6 * Copyright (c) 1992, 1993
7 * The Regents of the University of California. All rights reserved.
9 * This code is derived from software contributed to Berkeley by
10 * Keith Muller of the University of California, San Diego.
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. All advertising materials mentioning features or use of this software
21 * must display the following acknowledgement:
22 * This product includes software developed by the University of
23 * California, Berkeley and its contributors.
24 * 4. Neither the name of the University nor the names of its contributors
25 * may be used to endorse or promote products derived from this software
26 * without specific prior written permission.
28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
43 static char sccsid[] = "@(#)cpio.c 8.1 (Berkeley) 5/31/93";
45 static char rcsid[] = "$OpenBSD: cpio.c,v 1.5 1997/07/25 18:58:28 mickey Exp $";
49 #include <sys/types.h>
50 #include <sys/sysmacros.h>
53 #include <sys/param.h>
62 static int rd_nm __P((register ARCHD *, int));
63 static int rd_ln_nm __P((register ARCHD *));
64 static int com_rd __P((register ARCHD *));
67 * Routines which support the different cpio versions
70 static int swp_head; /* binary cpio header byte swap */
73 * Routines common to all versions of cpio
78 * Fire up the hard link detection code
80 * 0 if ok -1 otherwise (the return values of lnk_start())
96 * Called to determine if a header block is a valid trailer. We are
97 * passed the block, the in_sync flag (which tells us we are in resync
98 * mode; looking for a valid header), and cnt (which starts at zero)
99 * which is used to count the number of empty blocks we have seen so far.
101 * 0 if a valid trailer, -1 if not a valid trailer,
106 cpio_trail(register ARCHD *arcn)
110 register ARCHD *arcn;
114 * look for trailer id in file we are about to process
116 if ((strcmp(arcn->name, TRAILER) == 0) && (arcn->sb.st_size == 0))
123 * operations common to all cpio read functions.
130 com_rd(register ARCHD *arcn)
134 register ARCHD *arcn;
139 arcn->org_name = arcn->name;
140 switch(arcn->sb.st_mode & C_IFMT) {
142 arcn->type = PAX_FIF;
145 arcn->type = PAX_DIR;
148 arcn->type = PAX_BLK;
151 arcn->type = PAX_CHR;
154 arcn->type = PAX_SLK;
157 arcn->type = PAX_SCK;
163 * we have file data, set up skip (pad is set in the format
166 arcn->sb.st_mode = (arcn->sb.st_mode & 0xfff) | C_ISREG;
167 arcn->type = PAX_REG;
168 arcn->skip = arcn->sb.st_size;
171 if (chk_lnk(arcn) < 0)
178 * write the special file with the name trailer in the proper format
180 * result of the write of the trailer from the cpio specific write func
194 * create a trailer request and call the proper format write function
196 memset(&last, 0, sizeof(last));
197 last.nlen = sizeof(TRAILER) - 1;
199 last.sb.st_nlink = 1;
200 (void)strcpy(last.name, TRAILER);
201 return((*frmt->wr)(&last));
206 * read in the file name which follows the cpio header
208 * 0 if ok, -1 otherwise
213 rd_nm(register ARCHD *arcn, int nsz)
217 register ARCHD *arcn;
222 * do not even try bogus values
224 if ((nsz == 0) || (nsz > sizeof(arcn->name))) {
225 paxwarn(1, "Cpio file name length %d is out of range", nsz);
230 * read the name and make sure it is not empty and is \0 terminated
232 if ((rd_wrbuf(arcn->name,nsz) != nsz) || (arcn->name[nsz-1] != '\0') ||
233 (arcn->name[0] == '\0')) {
234 paxwarn(1, "Cpio file name in header is corrupted");
242 * read in the link name for a file with links. The link name is stored
243 * like file data (and is NOT \0 terminated!)
245 * 0 if ok, -1 otherwise
250 rd_ln_nm(register ARCHD *arcn)
254 register ARCHD *arcn;
258 * check the length specified for bogus values
260 if ((arcn->sb.st_size == 0) ||
261 (arcn->sb.st_size >= sizeof(arcn->ln_name))) {
263 paxwarn(1, "Cpio link name length is invalid: %lu",
266 paxwarn(1, "Cpio link name length is invalid: %qu",
273 * read in the link name and \0 terminate it
275 if (rd_wrbuf(arcn->ln_name, (int)arcn->sb.st_size) !=
276 (int)arcn->sb.st_size) {
277 paxwarn(1, "Cpio link name read error");
280 arcn->ln_nlen = arcn->sb.st_size;
281 arcn->ln_name[arcn->ln_nlen] = '\0';
284 * watch out for those empty link names
286 if (arcn->ln_name[0] == '\0') {
287 paxwarn(1, "Cpio link name is corrupt");
294 * Routines common to the extended byte oriented cpio format
299 * determine if a block given to us is a valid extended byte oriented
302 * 0 if a valid header, -1 otherwise
307 cpio_id(char *blk, int size)
315 if ((size < sizeof(HD_CPIO)) ||
316 (strncmp(blk, AMAGIC, sizeof(AMAGIC) - 1) != 0))
323 * determine if a buffer is a byte oriented extended cpio archive entry.
324 * convert and store the values in the ARCHD parameter.
326 * 0 if a valid header, -1 otherwise.
331 cpio_rd(register ARCHD *arcn, register char *buf)
335 register ARCHD *arcn;
340 register HD_CPIO *hd;
343 * check that this is a valid header, if not return -1
345 if (cpio_id(buf, sizeof(HD_CPIO)) < 0)
350 * byte oriented cpio (posix) does not have padding! extract the octal
351 * ascii fields from the header
354 arcn->sb.st_dev = (dev_t)asc_ul(hd->c_dev, sizeof(hd->c_dev), OCT);
355 arcn->sb.st_ino = (ino_t)asc_ul(hd->c_ino, sizeof(hd->c_ino), OCT);
356 arcn->sb.st_mode = (mode_t)asc_ul(hd->c_mode, sizeof(hd->c_mode), OCT);
357 arcn->sb.st_uid = (uid_t)asc_ul(hd->c_uid, sizeof(hd->c_uid), OCT);
358 arcn->sb.st_gid = (gid_t)asc_ul(hd->c_gid, sizeof(hd->c_gid), OCT);
359 arcn->sb.st_nlink = (nlink_t)asc_ul(hd->c_nlink, sizeof(hd->c_nlink),
361 arcn->sb.st_rdev = (dev_t)asc_ul(hd->c_rdev, sizeof(hd->c_rdev), OCT);
362 arcn->sb.st_mtime = (time_t)asc_ul(hd->c_mtime, sizeof(hd->c_mtime),
364 arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime;
366 arcn->sb.st_size = (off_t)asc_ul(hd->c_filesize,sizeof(hd->c_filesize),
369 arcn->sb.st_size = (off_t)asc_uqd(hd->c_filesize,sizeof(hd->c_filesize),
374 * check name size and if valid, read in the name of this entry (name
375 * follows header in the archive)
377 if ((nsz = (int)asc_ul(hd->c_namesize,sizeof(hd->c_namesize),OCT)) < 2)
379 arcn->nlen = nsz - 1;
380 if (rd_nm(arcn, nsz) < 0)
383 if (((arcn->sb.st_mode&C_IFMT) != C_ISLNK)||(arcn->sb.st_size == 0)) {
385 * no link name to read for this file
388 arcn->ln_name[0] = '\0';
389 return(com_rd(arcn));
393 * check link name size and read in the link name. Link names are
394 * stored like file data.
396 if (rd_ln_nm(arcn) < 0)
400 * we have a valid header (with a link)
402 return(com_rd(arcn));
407 * no cleanup needed here, just return size of the trailer (for append)
409 * size of trailer header in this format
420 return((off_t)(sizeof(HD_CPIO) + sizeof(TRAILER)));
425 * start up the device mapping table
427 * 0 if ok, -1 otherwise (what dev_start() returns)
443 * copy the data in the ARCHD to buffer in extended byte oriented cpio
446 * 0 if file has data to be written after the header, 1 if file has NO
447 * data to write after the header, -1 if archive write failed
452 cpio_wr(register ARCHD *arcn)
456 register ARCHD *arcn;
459 register HD_CPIO *hd;
461 char hdblk[sizeof(HD_CPIO)];
464 * check and repair truncated device and inode fields in the header
466 if (map_dev(arcn, (u_long)CPIO_MASK, (u_long)CPIO_MASK) < 0)
470 nsz = arcn->nlen + 1;
471 hd = (HD_CPIO *)hdblk;
472 if ((arcn->type != PAX_BLK) && (arcn->type != PAX_CHR))
473 arcn->sb.st_rdev = 0;
480 * set data size for file data
483 if (ul_asc((u_long)arcn->sb.st_size, hd->c_filesize,
484 sizeof(hd->c_filesize), OCT)) {
486 if (uqd_asc((u_quad_t)arcn->sb.st_size, hd->c_filesize,
487 sizeof(hd->c_filesize), OCT)) {
489 paxwarn(1,"File is too large for cpio format %s",
496 * set data size to hold link name
498 if (ul_asc((u_long)arcn->ln_nlen, hd->c_filesize,
499 sizeof(hd->c_filesize), OCT))
504 * all other file types have no file data
506 if (ul_asc((u_long)0, hd->c_filesize, sizeof(hd->c_filesize),
513 * copy the values to the header using octal ascii
515 if (ul_asc((u_long)MAGIC, hd->c_magic, sizeof(hd->c_magic), OCT) ||
516 ul_asc((u_long)arcn->sb.st_dev, hd->c_dev, sizeof(hd->c_dev),
518 ul_asc((u_long)arcn->sb.st_ino, hd->c_ino, sizeof(hd->c_ino),
520 ul_asc((u_long)arcn->sb.st_mode, hd->c_mode, sizeof(hd->c_mode),
522 ul_asc((u_long)arcn->sb.st_uid, hd->c_uid, sizeof(hd->c_uid),
524 ul_asc((u_long)arcn->sb.st_gid, hd->c_gid, sizeof(hd->c_gid),
526 ul_asc((u_long)arcn->sb.st_nlink, hd->c_nlink, sizeof(hd->c_nlink),
528 ul_asc((u_long)arcn->sb.st_rdev, hd->c_rdev, sizeof(hd->c_rdev),
530 ul_asc((u_long)arcn->sb.st_mtime,hd->c_mtime,sizeof(hd->c_mtime),
532 ul_asc((u_long)nsz, hd->c_namesize, sizeof(hd->c_namesize), OCT))
536 * write the file name to the archive
538 if ((wr_rdbuf(hdblk, (int)sizeof(HD_CPIO)) < 0) ||
539 (wr_rdbuf(arcn->name, nsz) < 0)) {
540 paxwarn(1, "Unable to write cpio header for %s", arcn->org_name);
545 * if this file has data, we are done. The caller will write the file
546 * data, if we are link tell caller we are done, go to next file
548 if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG) ||
549 (arcn->type == PAX_HRG))
551 if (arcn->type != PAX_SLK)
555 * write the link name to the archive, tell the caller to go to the
556 * next file as we are done.
558 if (wr_rdbuf(arcn->ln_name, arcn->ln_nlen) < 0) {
559 paxwarn(1,"Unable to write cpio link name for %s",arcn->org_name);
566 * header field is out of range
568 paxwarn(1, "Cpio header field is too small to store file %s",
574 * Routines common to the system VR4 version of cpio (with/without file CRC)
579 * determine if a block given to us is a valid system VR4 cpio header
580 * WITHOUT crc. WATCH it the magic cookies are in OCTAL, the header
583 * 0 if a valid header, -1 otherwise
588 vcpio_id(char *blk, int size)
596 if ((size < sizeof(HD_VCPIO)) ||
597 (strncmp(blk, AVMAGIC, sizeof(AVMAGIC) - 1) != 0))
604 * determine if a block given to us is a valid system VR4 cpio header
605 * WITH crc. WATCH it the magic cookies are in OCTAL the header uses HEX
607 * 0 if a valid header, -1 otherwise
612 crc_id(char *blk, int size)
620 if ((size < sizeof(HD_VCPIO)) ||
621 (strncmp(blk, AVCMAGIC, sizeof(AVCMAGIC) - 1) != 0))
628 w set file data CRC calculations. Fire up the hard link detection code
630 * 0 if ok -1 otherwise (the return values of lnk_start())
647 * determine if a buffer is a system VR4 archive entry. (with/without CRC)
648 * convert and store the values in the ARCHD parameter.
650 * 0 if a valid header, -1 otherwise.
655 vcpio_rd(register ARCHD *arcn, register char *buf)
659 register ARCHD *arcn;
663 register HD_VCPIO *hd;
669 * during the id phase it was determined if we were using CRC, use the
673 if (crc_id(buf, sizeof(HD_VCPIO)) < 0)
676 if (vcpio_id(buf, sizeof(HD_VCPIO)) < 0)
680 hd = (HD_VCPIO *)buf;
684 * extract the hex ascii fields from the header
686 arcn->sb.st_ino = (ino_t)asc_ul(hd->c_ino, sizeof(hd->c_ino), HEX);
687 arcn->sb.st_mode = (mode_t)asc_ul(hd->c_mode, sizeof(hd->c_mode), HEX);
688 arcn->sb.st_uid = (uid_t)asc_ul(hd->c_uid, sizeof(hd->c_uid), HEX);
689 arcn->sb.st_gid = (gid_t)asc_ul(hd->c_gid, sizeof(hd->c_gid), HEX);
690 arcn->sb.st_mtime = (time_t)asc_ul(hd->c_mtime,sizeof(hd->c_mtime),HEX);
691 arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime;
693 arcn->sb.st_size = (off_t)asc_ul(hd->c_filesize,
694 sizeof(hd->c_filesize), HEX);
696 arcn->sb.st_size = (off_t)asc_uqd(hd->c_filesize,
697 sizeof(hd->c_filesize), HEX);
699 arcn->sb.st_nlink = (nlink_t)asc_ul(hd->c_nlink, sizeof(hd->c_nlink),
701 devmajor = (dev_t)asc_ul(hd->c_maj, sizeof(hd->c_maj), HEX);
702 devminor = (dev_t)asc_ul(hd->c_min, sizeof(hd->c_min), HEX);
703 arcn->sb.st_dev = TODEV(devmajor, devminor);
704 devmajor = (dev_t)asc_ul(hd->c_rmaj, sizeof(hd->c_maj), HEX);
705 devminor = (dev_t)asc_ul(hd->c_rmin, sizeof(hd->c_min), HEX);
706 arcn->sb.st_rdev = TODEV(devmajor, devminor);
707 arcn->crc = asc_ul(hd->c_chksum, sizeof(hd->c_chksum), HEX);
710 * check the length of the file name, if ok read it in, return -1 if
713 if ((nsz = (int)asc_ul(hd->c_namesize,sizeof(hd->c_namesize),HEX)) < 2)
715 arcn->nlen = nsz - 1;
716 if (rd_nm(arcn, nsz) < 0)
720 * skip padding. header + filename is aligned to 4 byte boundries
722 if (rd_skip((off_t)(VCPIO_PAD(sizeof(HD_VCPIO) + nsz))) < 0)
726 * if not a link (or a file with no data), calculate pad size (for
727 * padding which follows the file data), clear the link name and return
729 if (((arcn->sb.st_mode&C_IFMT) != C_ISLNK)||(arcn->sb.st_size == 0)) {
731 * we have a valid header (not a link)
734 arcn->ln_name[0] = '\0';
735 arcn->pad = VCPIO_PAD(arcn->sb.st_size);
736 return(com_rd(arcn));
740 * read in the link name and skip over the padding
742 if ((rd_ln_nm(arcn) < 0) ||
743 (rd_skip((off_t)(VCPIO_PAD(arcn->sb.st_size))) < 0))
747 * we have a valid header (with a link)
749 return(com_rd(arcn));
754 * no cleanup needed here, just return size of the trailer (for append)
756 * size of trailer header in this format
767 return((off_t)(sizeof(HD_VCPIO) + sizeof(TRAILER) +
768 (VCPIO_PAD(sizeof(HD_VCPIO) + sizeof(TRAILER)))));
773 * start up the device mapping table, enable crc file calculation
775 * 0 if ok, -1 otherwise (what dev_start() returns)
792 * copy the data in the ARCHD to buffer in system VR4 cpio
793 * (with/without crc) format.
795 * 0 if file has data to be written after the header, 1 if file has
796 * NO data to write after the header, -1 if archive write failed
801 vcpio_wr(register ARCHD *arcn)
805 register ARCHD *arcn;
808 register HD_VCPIO *hd;
810 char hdblk[sizeof(HD_VCPIO)];
813 * check and repair truncated device and inode fields in the cpio
816 if (map_dev(arcn, (u_long)VCPIO_MASK, (u_long)VCPIO_MASK) < 0)
818 nsz = arcn->nlen + 1;
819 hd = (HD_VCPIO *)hdblk;
820 if ((arcn->type != PAX_BLK) && (arcn->type != PAX_CHR))
821 arcn->sb.st_rdev = 0;
824 * add the proper magic value depending whether we were asked for
825 * file data crc's, and the crc if needed.
828 if (ul_asc((u_long)VCMAGIC, hd->c_magic, sizeof(hd->c_magic),
830 ul_asc((u_long)arcn->crc,hd->c_chksum,sizeof(hd->c_chksum),
834 if (ul_asc((u_long)VMAGIC, hd->c_magic, sizeof(hd->c_magic),
836 ul_asc((u_long)0L, hd->c_chksum, sizeof(hd->c_chksum),HEX))
845 * caller will copy file data to the archive. tell him how
848 arcn->pad = VCPIO_PAD(arcn->sb.st_size);
850 if (ul_asc((u_long)arcn->sb.st_size, hd->c_filesize,
851 sizeof(hd->c_filesize), HEX)) {
853 if (uqd_asc((u_quad_t)arcn->sb.st_size, hd->c_filesize,
854 sizeof(hd->c_filesize), HEX)) {
856 paxwarn(1,"File is too large for sv4cpio format %s",
863 * no file data for the caller to process, the file data has
864 * the size of the link
867 if (ul_asc((u_long)arcn->ln_nlen, hd->c_filesize,
868 sizeof(hd->c_filesize), HEX))
873 * no file data for the caller to process
876 if (ul_asc((u_long)0L, hd->c_filesize, sizeof(hd->c_filesize),
883 * set the other fields in the header
885 if (ul_asc((u_long)arcn->sb.st_ino, hd->c_ino, sizeof(hd->c_ino),
887 ul_asc((u_long)arcn->sb.st_mode, hd->c_mode, sizeof(hd->c_mode),
889 ul_asc((u_long)arcn->sb.st_uid, hd->c_uid, sizeof(hd->c_uid),
891 ul_asc((u_long)arcn->sb.st_gid, hd->c_gid, sizeof(hd->c_gid),
893 ul_asc((u_long)arcn->sb.st_mtime, hd->c_mtime, sizeof(hd->c_mtime),
895 ul_asc((u_long)arcn->sb.st_nlink, hd->c_nlink, sizeof(hd->c_nlink),
897 ul_asc((u_long)MAJOR(arcn->sb.st_dev),hd->c_maj, sizeof(hd->c_maj),
899 ul_asc((u_long)MINOR(arcn->sb.st_dev),hd->c_min, sizeof(hd->c_min),
901 ul_asc((u_long)MAJOR(arcn->sb.st_rdev),hd->c_rmaj,sizeof(hd->c_maj),
903 ul_asc((u_long)MINOR(arcn->sb.st_rdev),hd->c_rmin,sizeof(hd->c_min),
905 ul_asc((u_long)nsz, hd->c_namesize, sizeof(hd->c_namesize), HEX))
909 * write the header, the file name and padding as required.
911 if ((wr_rdbuf(hdblk, (int)sizeof(HD_VCPIO)) < 0) ||
912 (wr_rdbuf(arcn->name, (int)nsz) < 0) ||
913 (wr_skip((off_t)(VCPIO_PAD(sizeof(HD_VCPIO) + nsz))) < 0)) {
914 paxwarn(1,"Could not write sv4cpio header for %s",arcn->org_name);
919 * if we have file data, tell the caller we are done, copy the file
921 if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG) ||
922 (arcn->type == PAX_HRG))
926 * if we are not a link, tell the caller we are done, go to next file
928 if (arcn->type != PAX_SLK)
932 * write the link name, tell the caller we are done.
934 if ((wr_rdbuf(arcn->ln_name, arcn->ln_nlen) < 0) ||
935 (wr_skip((off_t)(VCPIO_PAD(arcn->ln_nlen))) < 0)) {
936 paxwarn(1,"Could not write sv4cpio link name for %s",
944 * header field is out of range
946 paxwarn(1,"Sv4cpio header field is too small for file %s",arcn->org_name);
951 * Routines common to the old binary header cpio
956 * determine if a block given to us is a old binary cpio header
957 * (with/without header byte swapping)
959 * 0 if a valid header, -1 otherwise
964 bcpio_id(char *blk, int size)
972 if (size < sizeof(HD_BCPIO))
976 * check both normal and byte swapped magic cookies
978 if (((u_short)SHRT_EXT(blk)) == MAGIC)
980 if (((u_short)RSHRT_EXT(blk)) == MAGIC) {
990 * determine if a buffer is a old binary archive entry. (it may have byte
991 * swapped header) convert and store the values in the ARCHD parameter.
992 * This is a very old header format and should not really be used.
994 * 0 if a valid header, -1 otherwise.
999 bcpio_rd(register ARCHD *arcn, register char *buf)
1003 register ARCHD *arcn;
1007 register HD_BCPIO *hd;
1013 if (bcpio_id(buf, sizeof(HD_BCPIO)) < 0)
1017 hd = (HD_BCPIO *)buf;
1020 * header has swapped bytes on 16 bit boundries
1022 arcn->sb.st_dev = (dev_t)(RSHRT_EXT(hd->h_dev));
1023 arcn->sb.st_ino = (ino_t)(RSHRT_EXT(hd->h_ino));
1024 arcn->sb.st_mode = (mode_t)(RSHRT_EXT(hd->h_mode));
1025 arcn->sb.st_uid = (uid_t)(RSHRT_EXT(hd->h_uid));
1026 arcn->sb.st_gid = (gid_t)(RSHRT_EXT(hd->h_gid));
1027 arcn->sb.st_nlink = (nlink_t)(RSHRT_EXT(hd->h_nlink));
1028 arcn->sb.st_rdev = (dev_t)(RSHRT_EXT(hd->h_rdev));
1029 arcn->sb.st_mtime = (time_t)(RSHRT_EXT(hd->h_mtime_1));
1030 arcn->sb.st_mtime = (arcn->sb.st_mtime << 16) |
1031 ((time_t)(RSHRT_EXT(hd->h_mtime_2)));
1032 arcn->sb.st_size = (off_t)(RSHRT_EXT(hd->h_filesize_1));
1033 arcn->sb.st_size = (arcn->sb.st_size << 16) |
1034 ((off_t)(RSHRT_EXT(hd->h_filesize_2)));
1035 nsz = (int)(RSHRT_EXT(hd->h_namesize));
1037 arcn->sb.st_dev = (dev_t)(SHRT_EXT(hd->h_dev));
1038 arcn->sb.st_ino = (ino_t)(SHRT_EXT(hd->h_ino));
1039 arcn->sb.st_mode = (mode_t)(SHRT_EXT(hd->h_mode));
1040 arcn->sb.st_uid = (uid_t)(SHRT_EXT(hd->h_uid));
1041 arcn->sb.st_gid = (gid_t)(SHRT_EXT(hd->h_gid));
1042 arcn->sb.st_nlink = (nlink_t)(SHRT_EXT(hd->h_nlink));
1043 arcn->sb.st_rdev = (dev_t)(SHRT_EXT(hd->h_rdev));
1044 arcn->sb.st_mtime = (time_t)(SHRT_EXT(hd->h_mtime_1));
1045 arcn->sb.st_mtime = (arcn->sb.st_mtime << 16) |
1046 ((time_t)(SHRT_EXT(hd->h_mtime_2)));
1047 arcn->sb.st_size = (off_t)(SHRT_EXT(hd->h_filesize_1));
1048 arcn->sb.st_size = (arcn->sb.st_size << 16) |
1049 ((off_t)(SHRT_EXT(hd->h_filesize_2)));
1050 nsz = (int)(SHRT_EXT(hd->h_namesize));
1052 arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime;
1055 * check the file name size, if bogus give up. otherwise read the file
1060 arcn->nlen = nsz - 1;
1061 if (rd_nm(arcn, nsz) < 0)
1065 * header + file name are aligned to 2 byte boundries, skip if needed
1067 if (rd_skip((off_t)(BCPIO_PAD(sizeof(HD_BCPIO) + nsz))) < 0)
1071 * if not a link (or a file with no data), calculate pad size (for
1072 * padding which follows the file data), clear the link name and return
1074 if (((arcn->sb.st_mode & C_IFMT) != C_ISLNK)||(arcn->sb.st_size == 0)){
1076 * we have a valid header (not a link)
1079 arcn->ln_name[0] = '\0';
1080 arcn->pad = BCPIO_PAD(arcn->sb.st_size);
1081 return(com_rd(arcn));
1084 if ((rd_ln_nm(arcn) < 0) ||
1085 (rd_skip((off_t)(BCPIO_PAD(arcn->sb.st_size))) < 0))
1089 * we have a valid header (with a link)
1091 return(com_rd(arcn));
1096 * no cleanup needed here, just return size of the trailer (for append)
1098 * size of trailer header in this format
1109 return((off_t)(sizeof(HD_BCPIO) + sizeof(TRAILER) +
1110 (BCPIO_PAD(sizeof(HD_BCPIO) + sizeof(TRAILER)))));
1115 * copy the data in the ARCHD to buffer in old binary cpio format
1116 * There is a real chance of field overflow with this critter. So we
1117 * always check the conversion is ok. nobody in his their right mind
1118 * should write an achive in this format...
1120 * 0 if file has data to be written after the header, 1 if file has NO
1121 * data to write after the header, -1 if archive write failed
1126 bcpio_wr(register ARCHD *arcn)
1130 register ARCHD *arcn;
1133 register HD_BCPIO *hd;
1135 char hdblk[sizeof(HD_BCPIO)];
1141 * check and repair truncated device and inode fields in the cpio
1144 if (map_dev(arcn, (u_long)BCPIO_MASK, (u_long)BCPIO_MASK) < 0)
1147 if ((arcn->type != PAX_BLK) && (arcn->type != PAX_CHR))
1148 arcn->sb.st_rdev = 0;
1149 hd = (HD_BCPIO *)hdblk;
1151 switch(arcn->type) {
1156 * caller will copy file data to the archive. tell him how
1159 arcn->pad = BCPIO_PAD(arcn->sb.st_size);
1160 hd->h_filesize_1[0] = CHR_WR_0(arcn->sb.st_size);
1161 hd->h_filesize_1[1] = CHR_WR_1(arcn->sb.st_size);
1162 hd->h_filesize_2[0] = CHR_WR_2(arcn->sb.st_size);
1163 hd->h_filesize_2[1] = CHR_WR_3(arcn->sb.st_size);
1164 t_offt = (off_t)(SHRT_EXT(hd->h_filesize_1));
1165 t_offt = (t_offt<<16) | ((off_t)(SHRT_EXT(hd->h_filesize_2)));
1166 if (arcn->sb.st_size != t_offt) {
1167 paxwarn(1,"File is too large for bcpio format %s",
1174 * no file data for the caller to process, the file data has
1175 * the size of the link
1178 hd->h_filesize_1[0] = CHR_WR_0(arcn->ln_nlen);
1179 hd->h_filesize_1[1] = CHR_WR_1(arcn->ln_nlen);
1180 hd->h_filesize_2[0] = CHR_WR_2(arcn->ln_nlen);
1181 hd->h_filesize_2[1] = CHR_WR_3(arcn->ln_nlen);
1182 t_int = (int)(SHRT_EXT(hd->h_filesize_1));
1183 t_int = (t_int << 16) | ((int)(SHRT_EXT(hd->h_filesize_2)));
1184 if (arcn->ln_nlen != t_int)
1189 * no file data for the caller to process
1192 hd->h_filesize_1[0] = (char)0;
1193 hd->h_filesize_1[1] = (char)0;
1194 hd->h_filesize_2[0] = (char)0;
1195 hd->h_filesize_2[1] = (char)0;
1200 * build up the rest of the fields
1202 hd->h_magic[0] = CHR_WR_2(MAGIC);
1203 hd->h_magic[1] = CHR_WR_3(MAGIC);
1204 hd->h_dev[0] = CHR_WR_2(arcn->sb.st_dev);
1205 hd->h_dev[1] = CHR_WR_3(arcn->sb.st_dev);
1206 if (arcn->sb.st_dev != (dev_t)(SHRT_EXT(hd->h_dev)))
1208 hd->h_ino[0] = CHR_WR_2(arcn->sb.st_ino);
1209 hd->h_ino[1] = CHR_WR_3(arcn->sb.st_ino);
1210 if (arcn->sb.st_ino != (ino_t)(SHRT_EXT(hd->h_ino)))
1212 hd->h_mode[0] = CHR_WR_2(arcn->sb.st_mode);
1213 hd->h_mode[1] = CHR_WR_3(arcn->sb.st_mode);
1214 if (arcn->sb.st_mode != (mode_t)(SHRT_EXT(hd->h_mode)))
1216 hd->h_uid[0] = CHR_WR_2(arcn->sb.st_uid);
1217 hd->h_uid[1] = CHR_WR_3(arcn->sb.st_uid);
1218 if (arcn->sb.st_uid != (uid_t)(SHRT_EXT(hd->h_uid)))
1220 hd->h_gid[0] = CHR_WR_2(arcn->sb.st_gid);
1221 hd->h_gid[1] = CHR_WR_3(arcn->sb.st_gid);
1222 if (arcn->sb.st_gid != (gid_t)(SHRT_EXT(hd->h_gid)))
1224 hd->h_nlink[0] = CHR_WR_2(arcn->sb.st_nlink);
1225 hd->h_nlink[1] = CHR_WR_3(arcn->sb.st_nlink);
1226 if (arcn->sb.st_nlink != (nlink_t)(SHRT_EXT(hd->h_nlink)))
1228 hd->h_rdev[0] = CHR_WR_2(arcn->sb.st_rdev);
1229 hd->h_rdev[1] = CHR_WR_3(arcn->sb.st_rdev);
1230 if (arcn->sb.st_rdev != (dev_t)(SHRT_EXT(hd->h_rdev)))
1232 hd->h_mtime_1[0] = CHR_WR_0(arcn->sb.st_mtime);
1233 hd->h_mtime_1[1] = CHR_WR_1(arcn->sb.st_mtime);
1234 hd->h_mtime_2[0] = CHR_WR_2(arcn->sb.st_mtime);
1235 hd->h_mtime_2[1] = CHR_WR_3(arcn->sb.st_mtime);
1236 t_timet = (time_t)(SHRT_EXT(hd->h_mtime_1));
1237 t_timet = (t_timet << 16) | ((time_t)(SHRT_EXT(hd->h_mtime_2)));
1238 if (arcn->sb.st_mtime != t_timet)
1240 nsz = arcn->nlen + 1;
1241 hd->h_namesize[0] = CHR_WR_2(nsz);
1242 hd->h_namesize[1] = CHR_WR_3(nsz);
1243 if (nsz != (int)(SHRT_EXT(hd->h_namesize)))
1247 * write the header, the file name and padding as required.
1249 if ((wr_rdbuf(hdblk, (int)sizeof(HD_BCPIO)) < 0) ||
1250 (wr_rdbuf(arcn->name, nsz) < 0) ||
1251 (wr_skip((off_t)(BCPIO_PAD(sizeof(HD_BCPIO) + nsz))) < 0)) {
1252 paxwarn(1, "Could not write bcpio header for %s", arcn->org_name);
1257 * if we have file data, tell the caller we are done
1259 if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG) ||
1260 (arcn->type == PAX_HRG))
1264 * if we are not a link, tell the caller we are done, go to next file
1266 if (arcn->type != PAX_SLK)
1270 * write the link name, tell the caller we are done.
1272 if ((wr_rdbuf(arcn->ln_name, arcn->ln_nlen) < 0) ||
1273 (wr_skip((off_t)(BCPIO_PAD(arcn->ln_nlen))) < 0)) {
1274 paxwarn(1,"Could not write bcpio link name for %s",arcn->org_name);
1281 * header field is out of range
1283 paxwarn(1,"Bcpio header field is too small for file %s", arcn->org_name);