14b88c807SRodney W. Grimes /*- 24b88c807SRodney W. Grimes * Copyright (c) 1992 Keith Muller. 34b88c807SRodney W. Grimes * Copyright (c) 1992, 1993 44b88c807SRodney W. Grimes * The Regents of the University of California. All rights reserved. 54b88c807SRodney W. Grimes * 64b88c807SRodney W. Grimes * This code is derived from software contributed to Berkeley by 74b88c807SRodney W. Grimes * Keith Muller of the University of California, San Diego. 84b88c807SRodney W. Grimes * 94b88c807SRodney W. Grimes * Redistribution and use in source and binary forms, with or without 104b88c807SRodney W. Grimes * modification, are permitted provided that the following conditions 114b88c807SRodney W. Grimes * are met: 124b88c807SRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 134b88c807SRodney W. Grimes * notice, this list of conditions and the following disclaimer. 144b88c807SRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 154b88c807SRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 164b88c807SRodney W. Grimes * documentation and/or other materials provided with the distribution. 174b88c807SRodney W. Grimes * 3. All advertising materials mentioning features or use of this software 184b88c807SRodney W. Grimes * must display the following acknowledgement: 194b88c807SRodney W. Grimes * This product includes software developed by the University of 204b88c807SRodney W. Grimes * California, Berkeley and its contributors. 214b88c807SRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 224b88c807SRodney W. Grimes * may be used to endorse or promote products derived from this software 234b88c807SRodney W. Grimes * without specific prior written permission. 244b88c807SRodney W. Grimes * 254b88c807SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 264b88c807SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 274b88c807SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 284b88c807SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 294b88c807SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 304b88c807SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 314b88c807SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 324b88c807SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 334b88c807SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 344b88c807SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 354b88c807SRodney W. Grimes * SUCH DAMAGE. 364b88c807SRodney W. Grimes */ 374b88c807SRodney W. Grimes 384b88c807SRodney W. Grimes #ifndef lint 39c9a8d1f4SPhilippe Charnier #if 0 40c9a8d1f4SPhilippe Charnier static char sccsid[] = "@(#)cpio.c 8.1 (Berkeley) 5/31/93"; 41c9a8d1f4SPhilippe Charnier #endif 42c9a8d1f4SPhilippe Charnier static const char rcsid[] = 432a456239SPeter Wemm "$FreeBSD$"; 444b88c807SRodney W. Grimes #endif /* not lint */ 454b88c807SRodney W. Grimes 464b88c807SRodney W. Grimes #include <sys/types.h> 474b88c807SRodney W. Grimes #include <sys/time.h> 484b88c807SRodney W. Grimes #include <sys/stat.h> 494b88c807SRodney W. Grimes #include <string.h> 504b88c807SRodney W. Grimes #include <stdio.h> 514b88c807SRodney W. Grimes #include <unistd.h> 524b88c807SRodney W. Grimes #include <stdlib.h> 534b88c807SRodney W. Grimes #include "pax.h" 544b88c807SRodney W. Grimes #include "cpio.h" 554b88c807SRodney W. Grimes #include "extern.h" 564b88c807SRodney W. Grimes 57f789b261SWarner Losh static int rd_nm(ARCHD *, int); 58f789b261SWarner Losh static int rd_ln_nm(ARCHD *); 59f789b261SWarner Losh static int com_rd(ARCHD *); 604b88c807SRodney W. Grimes 614b88c807SRodney W. Grimes /* 624b88c807SRodney W. Grimes * Routines which support the different cpio versions 634b88c807SRodney W. Grimes */ 644b88c807SRodney W. Grimes 654b88c807SRodney W. Grimes static int swp_head; /* binary cpio header byte swap */ 664b88c807SRodney W. Grimes 674b88c807SRodney W. Grimes /* 684b88c807SRodney W. Grimes * Routines common to all versions of cpio 694b88c807SRodney W. Grimes */ 704b88c807SRodney W. Grimes 714b88c807SRodney W. Grimes /* 724b88c807SRodney W. Grimes * cpio_strd() 734b88c807SRodney W. Grimes * Fire up the hard link detection code 744b88c807SRodney W. Grimes * Return: 754b88c807SRodney W. Grimes * 0 if ok -1 otherwise (the return values of lnk_start()) 764b88c807SRodney W. Grimes */ 774b88c807SRodney W. Grimes 784b88c807SRodney W. Grimes int 794b88c807SRodney W. Grimes cpio_strd(void) 804b88c807SRodney W. Grimes { 814b88c807SRodney W. Grimes return(lnk_start()); 824b88c807SRodney W. Grimes } 834b88c807SRodney W. Grimes 844b88c807SRodney W. Grimes /* 854b88c807SRodney W. Grimes * cpio_trail() 864b88c807SRodney W. Grimes * Called to determine if a header block is a valid trailer. We are 874b88c807SRodney W. Grimes * passed the block, the in_sync flag (which tells us we are in resync 884b88c807SRodney W. Grimes * mode; looking for a valid header), and cnt (which starts at zero) 894b88c807SRodney W. Grimes * which is used to count the number of empty blocks we have seen so far. 904b88c807SRodney W. Grimes * Return: 914b88c807SRodney W. Grimes * 0 if a valid trailer, -1 if not a valid trailer, 924b88c807SRodney W. Grimes */ 934b88c807SRodney W. Grimes 944b88c807SRodney W. Grimes int 95f789b261SWarner Losh cpio_trail(ARCHD *arcn) 964b88c807SRodney W. Grimes { 974b88c807SRodney W. Grimes /* 984b88c807SRodney W. Grimes * look for trailer id in file we are about to process 994b88c807SRodney W. Grimes */ 1004b88c807SRodney W. Grimes if ((strcmp(arcn->name, TRAILER) == 0) && (arcn->sb.st_size == 0)) 1014b88c807SRodney W. Grimes return(0); 1024b88c807SRodney W. Grimes return(-1); 1034b88c807SRodney W. Grimes } 1044b88c807SRodney W. Grimes 1054b88c807SRodney W. Grimes /* 1064b88c807SRodney W. Grimes * com_rd() 1074b88c807SRodney W. Grimes * operations common to all cpio read functions. 1084b88c807SRodney W. Grimes * Return: 1094b88c807SRodney W. Grimes * 0 1104b88c807SRodney W. Grimes */ 1114b88c807SRodney W. Grimes 1124b88c807SRodney W. Grimes static int 113f789b261SWarner Losh com_rd(ARCHD *arcn) 1144b88c807SRodney W. Grimes { 1154b88c807SRodney W. Grimes arcn->skip = 0; 1164b88c807SRodney W. Grimes arcn->pat = NULL; 1174b88c807SRodney W. Grimes arcn->org_name = arcn->name; 1184b88c807SRodney W. Grimes switch(arcn->sb.st_mode & C_IFMT) { 1194b88c807SRodney W. Grimes case C_ISFIFO: 1204b88c807SRodney W. Grimes arcn->type = PAX_FIF; 1214b88c807SRodney W. Grimes break; 1224b88c807SRodney W. Grimes case C_ISDIR: 1234b88c807SRodney W. Grimes arcn->type = PAX_DIR; 1244b88c807SRodney W. Grimes break; 1254b88c807SRodney W. Grimes case C_ISBLK: 1264b88c807SRodney W. Grimes arcn->type = PAX_BLK; 1274b88c807SRodney W. Grimes break; 1284b88c807SRodney W. Grimes case C_ISCHR: 1294b88c807SRodney W. Grimes arcn->type = PAX_CHR; 1304b88c807SRodney W. Grimes break; 1314b88c807SRodney W. Grimes case C_ISLNK: 1324b88c807SRodney W. Grimes arcn->type = PAX_SLK; 1334b88c807SRodney W. Grimes break; 1344b88c807SRodney W. Grimes case C_ISOCK: 1354b88c807SRodney W. Grimes arcn->type = PAX_SCK; 1364b88c807SRodney W. Grimes break; 1374b88c807SRodney W. Grimes case C_ISCTG: 1384b88c807SRodney W. Grimes case C_ISREG: 1394b88c807SRodney W. Grimes default: 1404b88c807SRodney W. Grimes /* 1414b88c807SRodney W. Grimes * we have file data, set up skip (pad is set in the format 1424b88c807SRodney W. Grimes * specific sections) 1434b88c807SRodney W. Grimes */ 1444b88c807SRodney W. Grimes arcn->sb.st_mode = (arcn->sb.st_mode & 0xfff) | C_ISREG; 1454b88c807SRodney W. Grimes arcn->type = PAX_REG; 1464b88c807SRodney W. Grimes arcn->skip = arcn->sb.st_size; 1474b88c807SRodney W. Grimes break; 1484b88c807SRodney W. Grimes } 1494b88c807SRodney W. Grimes if (chk_lnk(arcn) < 0) 1504b88c807SRodney W. Grimes return(-1); 1514b88c807SRodney W. Grimes return(0); 1524b88c807SRodney W. Grimes } 1534b88c807SRodney W. Grimes 1544b88c807SRodney W. Grimes /* 1554b88c807SRodney W. Grimes * cpio_end_wr() 1564b88c807SRodney W. Grimes * write the special file with the name trailer in the proper format 1574b88c807SRodney W. Grimes * Return: 1584b88c807SRodney W. Grimes * result of the write of the trailer from the cpio specific write func 1594b88c807SRodney W. Grimes */ 1604b88c807SRodney W. Grimes 1614b88c807SRodney W. Grimes int 1624b88c807SRodney W. Grimes cpio_endwr(void) 1634b88c807SRodney W. Grimes { 1644b88c807SRodney W. Grimes ARCHD last; 1654b88c807SRodney W. Grimes 1664b88c807SRodney W. Grimes /* 1674b88c807SRodney W. Grimes * create a trailer request and call the proper format write function 1684b88c807SRodney W. Grimes */ 169778766feSKris Kennaway memset(&last, 0, sizeof(last)); 1704b88c807SRodney W. Grimes last.nlen = sizeof(TRAILER) - 1; 1714b88c807SRodney W. Grimes last.type = PAX_REG; 1724b88c807SRodney W. Grimes last.sb.st_nlink = 1; 1734b88c807SRodney W. Grimes (void)strcpy(last.name, TRAILER); 1744b88c807SRodney W. Grimes return((*frmt->wr)(&last)); 1754b88c807SRodney W. Grimes } 1764b88c807SRodney W. Grimes 1774b88c807SRodney W. Grimes /* 1784b88c807SRodney W. Grimes * rd_nam() 1794b88c807SRodney W. Grimes * read in the file name which follows the cpio header 1804b88c807SRodney W. Grimes * Return: 1814b88c807SRodney W. Grimes * 0 if ok, -1 otherwise 1824b88c807SRodney W. Grimes */ 1834b88c807SRodney W. Grimes 1844b88c807SRodney W. Grimes static int 185f789b261SWarner Losh rd_nm(ARCHD *arcn, int nsz) 1864b88c807SRodney W. Grimes { 1874b88c807SRodney W. Grimes /* 1884b88c807SRodney W. Grimes * do not even try bogus values 1894b88c807SRodney W. Grimes */ 1904b88c807SRodney W. Grimes if ((nsz == 0) || (nsz > sizeof(arcn->name))) { 191778766feSKris Kennaway paxwarn(1, "Cpio file name length %d is out of range", nsz); 1924b88c807SRodney W. Grimes return(-1); 1934b88c807SRodney W. Grimes } 1944b88c807SRodney W. Grimes 1954b88c807SRodney W. Grimes /* 1964b88c807SRodney W. Grimes * read the name and make sure it is not empty and is \0 terminated 1974b88c807SRodney W. Grimes */ 1984b88c807SRodney W. Grimes if ((rd_wrbuf(arcn->name,nsz) != nsz) || (arcn->name[nsz-1] != '\0') || 1994b88c807SRodney W. Grimes (arcn->name[0] == '\0')) { 200778766feSKris Kennaway paxwarn(1, "Cpio file name in header is corrupted"); 2014b88c807SRodney W. Grimes return(-1); 2024b88c807SRodney W. Grimes } 2034b88c807SRodney W. Grimes return(0); 2044b88c807SRodney W. Grimes } 2054b88c807SRodney W. Grimes 2064b88c807SRodney W. Grimes /* 2074b88c807SRodney W. Grimes * rd_ln_nm() 2084b88c807SRodney W. Grimes * read in the link name for a file with links. The link name is stored 2094b88c807SRodney W. Grimes * like file data (and is NOT \0 terminated!) 2104b88c807SRodney W. Grimes * Return: 2114b88c807SRodney W. Grimes * 0 if ok, -1 otherwise 2124b88c807SRodney W. Grimes */ 2134b88c807SRodney W. Grimes 2144b88c807SRodney W. Grimes static int 215f789b261SWarner Losh rd_ln_nm(ARCHD *arcn) 2164b88c807SRodney W. Grimes { 2174b88c807SRodney W. Grimes /* 2184b88c807SRodney W. Grimes * check the length specified for bogus values 2194b88c807SRodney W. Grimes */ 2204b88c807SRodney W. Grimes if ((arcn->sb.st_size == 0) || 2214b88c807SRodney W. Grimes (arcn->sb.st_size >= sizeof(arcn->ln_name))) { 2224b88c807SRodney W. Grimes # ifdef NET2_STAT 223778766feSKris Kennaway paxwarn(1, "Cpio link name length is invalid: %lu", 2244b88c807SRodney W. Grimes arcn->sb.st_size); 2254b88c807SRodney W. Grimes # else 226778766feSKris Kennaway paxwarn(1, "Cpio link name length is invalid: %qu", 2274b88c807SRodney W. Grimes arcn->sb.st_size); 2284b88c807SRodney W. Grimes # endif 2294b88c807SRodney W. Grimes return(-1); 2304b88c807SRodney W. Grimes } 2314b88c807SRodney W. Grimes 2324b88c807SRodney W. Grimes /* 2334b88c807SRodney W. Grimes * read in the link name and \0 terminate it 2344b88c807SRodney W. Grimes */ 2354b88c807SRodney W. Grimes if (rd_wrbuf(arcn->ln_name, (int)arcn->sb.st_size) != 2364b88c807SRodney W. Grimes (int)arcn->sb.st_size) { 237778766feSKris Kennaway paxwarn(1, "Cpio link name read error"); 2384b88c807SRodney W. Grimes return(-1); 2394b88c807SRodney W. Grimes } 2404b88c807SRodney W. Grimes arcn->ln_nlen = arcn->sb.st_size; 2414b88c807SRodney W. Grimes arcn->ln_name[arcn->ln_nlen] = '\0'; 2424b88c807SRodney W. Grimes 2434b88c807SRodney W. Grimes /* 2444b88c807SRodney W. Grimes * watch out for those empty link names 2454b88c807SRodney W. Grimes */ 2464b88c807SRodney W. Grimes if (arcn->ln_name[0] == '\0') { 247778766feSKris Kennaway paxwarn(1, "Cpio link name is corrupt"); 2484b88c807SRodney W. Grimes return(-1); 2494b88c807SRodney W. Grimes } 2504b88c807SRodney W. Grimes return(0); 2514b88c807SRodney W. Grimes } 2524b88c807SRodney W. Grimes 2534b88c807SRodney W. Grimes /* 2544b88c807SRodney W. Grimes * Routines common to the extended byte oriented cpio format 2554b88c807SRodney W. Grimes */ 2564b88c807SRodney W. Grimes 2574b88c807SRodney W. Grimes /* 2584b88c807SRodney W. Grimes * cpio_id() 2594b88c807SRodney W. Grimes * determine if a block given to us is a valid extended byte oriented 2604b88c807SRodney W. Grimes * cpio header 2614b88c807SRodney W. Grimes * Return: 2624b88c807SRodney W. Grimes * 0 if a valid header, -1 otherwise 2634b88c807SRodney W. Grimes */ 2644b88c807SRodney W. Grimes 2654b88c807SRodney W. Grimes int 2664b88c807SRodney W. Grimes cpio_id(char *blk, int size) 2674b88c807SRodney W. Grimes { 2684b88c807SRodney W. Grimes if ((size < sizeof(HD_CPIO)) || 2694b88c807SRodney W. Grimes (strncmp(blk, AMAGIC, sizeof(AMAGIC) - 1) != 0)) 2704b88c807SRodney W. Grimes return(-1); 2714b88c807SRodney W. Grimes return(0); 2724b88c807SRodney W. Grimes } 2734b88c807SRodney W. Grimes 2744b88c807SRodney W. Grimes /* 2754b88c807SRodney W. Grimes * cpio_rd() 2764b88c807SRodney W. Grimes * determine if a buffer is a byte oriented extended cpio archive entry. 2774b88c807SRodney W. Grimes * convert and store the values in the ARCHD parameter. 2784b88c807SRodney W. Grimes * Return: 2794b88c807SRodney W. Grimes * 0 if a valid header, -1 otherwise. 2804b88c807SRodney W. Grimes */ 2814b88c807SRodney W. Grimes 2824b88c807SRodney W. Grimes int 283f789b261SWarner Losh cpio_rd(ARCHD *arcn, char *buf) 2844b88c807SRodney W. Grimes { 285f789b261SWarner Losh int nsz; 286f789b261SWarner Losh HD_CPIO *hd; 2874b88c807SRodney W. Grimes 2884b88c807SRodney W. Grimes /* 2894b88c807SRodney W. Grimes * check that this is a valid header, if not return -1 2904b88c807SRodney W. Grimes */ 2914b88c807SRodney W. Grimes if (cpio_id(buf, sizeof(HD_CPIO)) < 0) 2924b88c807SRodney W. Grimes return(-1); 2934b88c807SRodney W. Grimes hd = (HD_CPIO *)buf; 2944b88c807SRodney W. Grimes 2954b88c807SRodney W. Grimes /* 2964b88c807SRodney W. Grimes * byte oriented cpio (posix) does not have padding! extract the octal 2974b88c807SRodney W. Grimes * ascii fields from the header 2984b88c807SRodney W. Grimes */ 2994b88c807SRodney W. Grimes arcn->pad = 0L; 3004b88c807SRodney W. Grimes arcn->sb.st_dev = (dev_t)asc_ul(hd->c_dev, sizeof(hd->c_dev), OCT); 3014b88c807SRodney W. Grimes arcn->sb.st_ino = (ino_t)asc_ul(hd->c_ino, sizeof(hd->c_ino), OCT); 3024b88c807SRodney W. Grimes arcn->sb.st_mode = (mode_t)asc_ul(hd->c_mode, sizeof(hd->c_mode), OCT); 3034b88c807SRodney W. Grimes arcn->sb.st_uid = (uid_t)asc_ul(hd->c_uid, sizeof(hd->c_uid), OCT); 3044b88c807SRodney W. Grimes arcn->sb.st_gid = (gid_t)asc_ul(hd->c_gid, sizeof(hd->c_gid), OCT); 3054b88c807SRodney W. Grimes arcn->sb.st_nlink = (nlink_t)asc_ul(hd->c_nlink, sizeof(hd->c_nlink), 3064b88c807SRodney W. Grimes OCT); 3074b88c807SRodney W. Grimes arcn->sb.st_rdev = (dev_t)asc_ul(hd->c_rdev, sizeof(hd->c_rdev), OCT); 3082ad45bbeSMatthew Dillon #ifdef NET2_STAT 3094b88c807SRodney W. Grimes arcn->sb.st_mtime = (time_t)asc_ul(hd->c_mtime, sizeof(hd->c_mtime), 3104b88c807SRodney W. Grimes OCT); 3112ad45bbeSMatthew Dillon #else 3122ad45bbeSMatthew Dillon arcn->sb.st_mtime = (time_t)asc_uqd(hd->c_mtime, sizeof(hd->c_mtime), 3132ad45bbeSMatthew Dillon OCT); 3142ad45bbeSMatthew Dillon #endif 3154b88c807SRodney W. Grimes arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime; 3164b88c807SRodney W. Grimes #ifdef NET2_STAT 3174b88c807SRodney W. Grimes arcn->sb.st_size = (off_t)asc_ul(hd->c_filesize,sizeof(hd->c_filesize), 3184b88c807SRodney W. Grimes OCT); 3194b88c807SRodney W. Grimes #else 3204b88c807SRodney W. Grimes arcn->sb.st_size = (off_t)asc_uqd(hd->c_filesize,sizeof(hd->c_filesize), 3214b88c807SRodney W. Grimes OCT); 3224b88c807SRodney W. Grimes #endif 3234b88c807SRodney W. Grimes 3244b88c807SRodney W. Grimes /* 3254b88c807SRodney W. Grimes * check name size and if valid, read in the name of this entry (name 3264b88c807SRodney W. Grimes * follows header in the archive) 3274b88c807SRodney W. Grimes */ 3284b88c807SRodney W. Grimes if ((nsz = (int)asc_ul(hd->c_namesize,sizeof(hd->c_namesize),OCT)) < 2) 3294b88c807SRodney W. Grimes return(-1); 3304b88c807SRodney W. Grimes arcn->nlen = nsz - 1; 3314b88c807SRodney W. Grimes if (rd_nm(arcn, nsz) < 0) 3324b88c807SRodney W. Grimes return(-1); 3334b88c807SRodney W. Grimes 3344b88c807SRodney W. Grimes if (((arcn->sb.st_mode&C_IFMT) != C_ISLNK)||(arcn->sb.st_size == 0)) { 3354b88c807SRodney W. Grimes /* 3364b88c807SRodney W. Grimes * no link name to read for this file 3374b88c807SRodney W. Grimes */ 3384b88c807SRodney W. Grimes arcn->ln_nlen = 0; 3394b88c807SRodney W. Grimes arcn->ln_name[0] = '\0'; 3404b88c807SRodney W. Grimes return(com_rd(arcn)); 3414b88c807SRodney W. Grimes } 3424b88c807SRodney W. Grimes 3434b88c807SRodney W. Grimes /* 3444b88c807SRodney W. Grimes * check link name size and read in the link name. Link names are 3454b88c807SRodney W. Grimes * stored like file data. 3464b88c807SRodney W. Grimes */ 3474b88c807SRodney W. Grimes if (rd_ln_nm(arcn) < 0) 3484b88c807SRodney W. Grimes return(-1); 3494b88c807SRodney W. Grimes 3504b88c807SRodney W. Grimes /* 3514b88c807SRodney W. Grimes * we have a valid header (with a link) 3524b88c807SRodney W. Grimes */ 3534b88c807SRodney W. Grimes return(com_rd(arcn)); 3544b88c807SRodney W. Grimes } 3554b88c807SRodney W. Grimes 3564b88c807SRodney W. Grimes /* 3574b88c807SRodney W. Grimes * cpio_endrd() 3584b88c807SRodney W. Grimes * no cleanup needed here, just return size of the trailer (for append) 3594b88c807SRodney W. Grimes * Return: 3604b88c807SRodney W. Grimes * size of trailer header in this format 3614b88c807SRodney W. Grimes */ 3624b88c807SRodney W. Grimes 3634b88c807SRodney W. Grimes off_t 3644b88c807SRodney W. Grimes cpio_endrd(void) 3654b88c807SRodney W. Grimes { 3664b88c807SRodney W. Grimes return((off_t)(sizeof(HD_CPIO) + sizeof(TRAILER))); 3674b88c807SRodney W. Grimes } 3684b88c807SRodney W. Grimes 3694b88c807SRodney W. Grimes /* 3704b88c807SRodney W. Grimes * cpio_stwr() 3714b88c807SRodney W. Grimes * start up the device mapping table 3724b88c807SRodney W. Grimes * Return: 3734b88c807SRodney W. Grimes * 0 if ok, -1 otherwise (what dev_start() returns) 3744b88c807SRodney W. Grimes */ 3754b88c807SRodney W. Grimes 3764b88c807SRodney W. Grimes int 3774b88c807SRodney W. Grimes cpio_stwr(void) 3784b88c807SRodney W. Grimes { 3794b88c807SRodney W. Grimes return(dev_start()); 3804b88c807SRodney W. Grimes } 3814b88c807SRodney W. Grimes 3824b88c807SRodney W. Grimes /* 3834b88c807SRodney W. Grimes * cpio_wr() 3844b88c807SRodney W. Grimes * copy the data in the ARCHD to buffer in extended byte oriented cpio 3854b88c807SRodney W. Grimes * format. 3864b88c807SRodney W. Grimes * Return 3874b88c807SRodney W. Grimes * 0 if file has data to be written after the header, 1 if file has NO 3884b88c807SRodney W. Grimes * data to write after the header, -1 if archive write failed 3894b88c807SRodney W. Grimes */ 3904b88c807SRodney W. Grimes 3914b88c807SRodney W. Grimes int 392f789b261SWarner Losh cpio_wr(ARCHD *arcn) 3934b88c807SRodney W. Grimes { 394f789b261SWarner Losh HD_CPIO *hd; 395f789b261SWarner Losh int nsz; 3964b88c807SRodney W. Grimes char hdblk[sizeof(HD_CPIO)]; 3974b88c807SRodney W. Grimes 3984b88c807SRodney W. Grimes /* 3994b88c807SRodney W. Grimes * check and repair truncated device and inode fields in the header 4004b88c807SRodney W. Grimes */ 4014b88c807SRodney W. Grimes if (map_dev(arcn, (u_long)CPIO_MASK, (u_long)CPIO_MASK) < 0) 4024b88c807SRodney W. Grimes return(-1); 4034b88c807SRodney W. Grimes 4044b88c807SRodney W. Grimes arcn->pad = 0L; 4054b88c807SRodney W. Grimes nsz = arcn->nlen + 1; 4064b88c807SRodney W. Grimes hd = (HD_CPIO *)hdblk; 4074b88c807SRodney W. Grimes if ((arcn->type != PAX_BLK) && (arcn->type != PAX_CHR)) 4084b88c807SRodney W. Grimes arcn->sb.st_rdev = 0; 4094b88c807SRodney W. Grimes 4104b88c807SRodney W. Grimes switch(arcn->type) { 4114b88c807SRodney W. Grimes case PAX_CTG: 4124b88c807SRodney W. Grimes case PAX_REG: 4134b88c807SRodney W. Grimes case PAX_HRG: 4144b88c807SRodney W. Grimes /* 4154b88c807SRodney W. Grimes * set data size for file data 4164b88c807SRodney W. Grimes */ 4174b88c807SRodney W. Grimes # ifdef NET2_STAT 4184b88c807SRodney W. Grimes if (ul_asc((u_long)arcn->sb.st_size, hd->c_filesize, 4194b88c807SRodney W. Grimes sizeof(hd->c_filesize), OCT)) { 4204b88c807SRodney W. Grimes # else 4214b88c807SRodney W. Grimes if (uqd_asc((u_quad_t)arcn->sb.st_size, hd->c_filesize, 4224b88c807SRodney W. Grimes sizeof(hd->c_filesize), OCT)) { 4234b88c807SRodney W. Grimes # endif 424778766feSKris Kennaway paxwarn(1,"File is too large for cpio format %s", 4254b88c807SRodney W. Grimes arcn->org_name); 4264b88c807SRodney W. Grimes return(1); 4274b88c807SRodney W. Grimes } 4284b88c807SRodney W. Grimes break; 4294b88c807SRodney W. Grimes case PAX_SLK: 4304b88c807SRodney W. Grimes /* 4314b88c807SRodney W. Grimes * set data size to hold link name 4324b88c807SRodney W. Grimes */ 4334b88c807SRodney W. Grimes if (ul_asc((u_long)arcn->ln_nlen, hd->c_filesize, 4344b88c807SRodney W. Grimes sizeof(hd->c_filesize), OCT)) 4354b88c807SRodney W. Grimes goto out; 4364b88c807SRodney W. Grimes break; 4374b88c807SRodney W. Grimes default: 4384b88c807SRodney W. Grimes /* 4394b88c807SRodney W. Grimes * all other file types have no file data 4404b88c807SRodney W. Grimes */ 4414b88c807SRodney W. Grimes if (ul_asc((u_long)0, hd->c_filesize, sizeof(hd->c_filesize), 4424b88c807SRodney W. Grimes OCT)) 4434b88c807SRodney W. Grimes goto out; 4444b88c807SRodney W. Grimes break; 4454b88c807SRodney W. Grimes } 4464b88c807SRodney W. Grimes 4474b88c807SRodney W. Grimes /* 4484b88c807SRodney W. Grimes * copy the values to the header using octal ascii 4494b88c807SRodney W. Grimes */ 4504b88c807SRodney W. Grimes if (ul_asc((u_long)MAGIC, hd->c_magic, sizeof(hd->c_magic), OCT) || 4514b88c807SRodney W. Grimes ul_asc((u_long)arcn->sb.st_dev, hd->c_dev, sizeof(hd->c_dev), 4524b88c807SRodney W. Grimes OCT) || 4534b88c807SRodney W. Grimes ul_asc((u_long)arcn->sb.st_ino, hd->c_ino, sizeof(hd->c_ino), 4544b88c807SRodney W. Grimes OCT) || 4554b88c807SRodney W. Grimes ul_asc((u_long)arcn->sb.st_mode, hd->c_mode, sizeof(hd->c_mode), 4564b88c807SRodney W. Grimes OCT) || 4574b88c807SRodney W. Grimes ul_asc((u_long)arcn->sb.st_uid, hd->c_uid, sizeof(hd->c_uid), 4584b88c807SRodney W. Grimes OCT) || 4594b88c807SRodney W. Grimes ul_asc((u_long)arcn->sb.st_gid, hd->c_gid, sizeof(hd->c_gid), 4604b88c807SRodney W. Grimes OCT) || 4614b88c807SRodney W. Grimes ul_asc((u_long)arcn->sb.st_nlink, hd->c_nlink, sizeof(hd->c_nlink), 4624b88c807SRodney W. Grimes OCT) || 4634b88c807SRodney W. Grimes ul_asc((u_long)arcn->sb.st_rdev, hd->c_rdev, sizeof(hd->c_rdev), 4644b88c807SRodney W. Grimes OCT) || 4654b88c807SRodney W. Grimes ul_asc((u_long)arcn->sb.st_mtime,hd->c_mtime,sizeof(hd->c_mtime), 4664b88c807SRodney W. Grimes OCT) || 4674b88c807SRodney W. Grimes ul_asc((u_long)nsz, hd->c_namesize, sizeof(hd->c_namesize), OCT)) 4684b88c807SRodney W. Grimes goto out; 4694b88c807SRodney W. Grimes 4704b88c807SRodney W. Grimes /* 4714b88c807SRodney W. Grimes * write the file name to the archive 4724b88c807SRodney W. Grimes */ 4734b88c807SRodney W. Grimes if ((wr_rdbuf(hdblk, (int)sizeof(HD_CPIO)) < 0) || 4744b88c807SRodney W. Grimes (wr_rdbuf(arcn->name, nsz) < 0)) { 475778766feSKris Kennaway paxwarn(1, "Unable to write cpio header for %s", arcn->org_name); 4764b88c807SRodney W. Grimes return(-1); 4774b88c807SRodney W. Grimes } 4784b88c807SRodney W. Grimes 4794b88c807SRodney W. Grimes /* 4804b88c807SRodney W. Grimes * if this file has data, we are done. The caller will write the file 4814b88c807SRodney W. Grimes * data, if we are link tell caller we are done, go to next file 4824b88c807SRodney W. Grimes */ 4834b88c807SRodney W. Grimes if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG) || 4844b88c807SRodney W. Grimes (arcn->type == PAX_HRG)) 4854b88c807SRodney W. Grimes return(0); 4864b88c807SRodney W. Grimes if (arcn->type != PAX_SLK) 4874b88c807SRodney W. Grimes return(1); 4884b88c807SRodney W. Grimes 4894b88c807SRodney W. Grimes /* 4904b88c807SRodney W. Grimes * write the link name to the archive, tell the caller to go to the 4914b88c807SRodney W. Grimes * next file as we are done. 4924b88c807SRodney W. Grimes */ 4934b88c807SRodney W. Grimes if (wr_rdbuf(arcn->ln_name, arcn->ln_nlen) < 0) { 494778766feSKris Kennaway paxwarn(1,"Unable to write cpio link name for %s",arcn->org_name); 4954b88c807SRodney W. Grimes return(-1); 4964b88c807SRodney W. Grimes } 4974b88c807SRodney W. Grimes return(1); 4984b88c807SRodney W. Grimes 4994b88c807SRodney W. Grimes out: 5004b88c807SRodney W. Grimes /* 5014b88c807SRodney W. Grimes * header field is out of range 5024b88c807SRodney W. Grimes */ 503778766feSKris Kennaway paxwarn(1, "Cpio header field is too small to store file %s", 5044b88c807SRodney W. Grimes arcn->org_name); 5054b88c807SRodney W. Grimes return(1); 5064b88c807SRodney W. Grimes } 5074b88c807SRodney W. Grimes 5084b88c807SRodney W. Grimes /* 5094b88c807SRodney W. Grimes * Routines common to the system VR4 version of cpio (with/without file CRC) 5104b88c807SRodney W. Grimes */ 5114b88c807SRodney W. Grimes 5124b88c807SRodney W. Grimes /* 5134b88c807SRodney W. Grimes * vcpio_id() 5144b88c807SRodney W. Grimes * determine if a block given to us is a valid system VR4 cpio header 5154b88c807SRodney W. Grimes * WITHOUT crc. WATCH it the magic cookies are in OCTAL, the header 5164b88c807SRodney W. Grimes * uses HEX 5174b88c807SRodney W. Grimes * Return: 5184b88c807SRodney W. Grimes * 0 if a valid header, -1 otherwise 5194b88c807SRodney W. Grimes */ 5204b88c807SRodney W. Grimes 5214b88c807SRodney W. Grimes int 5224b88c807SRodney W. Grimes vcpio_id(char *blk, int size) 5234b88c807SRodney W. Grimes { 5244b88c807SRodney W. Grimes if ((size < sizeof(HD_VCPIO)) || 5254b88c807SRodney W. Grimes (strncmp(blk, AVMAGIC, sizeof(AVMAGIC) - 1) != 0)) 5264b88c807SRodney W. Grimes return(-1); 5274b88c807SRodney W. Grimes return(0); 5284b88c807SRodney W. Grimes } 5294b88c807SRodney W. Grimes 5304b88c807SRodney W. Grimes /* 5314b88c807SRodney W. Grimes * crc_id() 5324b88c807SRodney W. Grimes * determine if a block given to us is a valid system VR4 cpio header 5334b88c807SRodney W. Grimes * WITH crc. WATCH it the magic cookies are in OCTAL the header uses HEX 5344b88c807SRodney W. Grimes * Return: 5354b88c807SRodney W. Grimes * 0 if a valid header, -1 otherwise 5364b88c807SRodney W. Grimes */ 5374b88c807SRodney W. Grimes 5384b88c807SRodney W. Grimes int 5394b88c807SRodney W. Grimes crc_id(char *blk, int size) 5404b88c807SRodney W. Grimes { 5414b88c807SRodney W. Grimes if ((size < sizeof(HD_VCPIO)) || 5424b88c807SRodney W. Grimes (strncmp(blk, AVCMAGIC, sizeof(AVCMAGIC) - 1) != 0)) 5434b88c807SRodney W. Grimes return(-1); 5444b88c807SRodney W. Grimes return(0); 5454b88c807SRodney W. Grimes } 5464b88c807SRodney W. Grimes 5474b88c807SRodney W. Grimes /* 5484b88c807SRodney W. Grimes * crc_strd() 5494b88c807SRodney W. Grimes w set file data CRC calculations. Fire up the hard link detection code 5504b88c807SRodney W. Grimes * Return: 5514b88c807SRodney W. Grimes * 0 if ok -1 otherwise (the return values of lnk_start()) 5524b88c807SRodney W. Grimes */ 5534b88c807SRodney W. Grimes 5544b88c807SRodney W. Grimes int 5554b88c807SRodney W. Grimes crc_strd(void) 5564b88c807SRodney W. Grimes { 5574b88c807SRodney W. Grimes docrc = 1; 5584b88c807SRodney W. Grimes return(lnk_start()); 5594b88c807SRodney W. Grimes } 5604b88c807SRodney W. Grimes 5614b88c807SRodney W. Grimes /* 5624b88c807SRodney W. Grimes * vcpio_rd() 5634b88c807SRodney W. Grimes * determine if a buffer is a system VR4 archive entry. (with/without CRC) 5644b88c807SRodney W. Grimes * convert and store the values in the ARCHD parameter. 5654b88c807SRodney W. Grimes * Return: 5664b88c807SRodney W. Grimes * 0 if a valid header, -1 otherwise. 5674b88c807SRodney W. Grimes */ 5684b88c807SRodney W. Grimes 5694b88c807SRodney W. Grimes int 570f789b261SWarner Losh vcpio_rd(ARCHD *arcn, char *buf) 5714b88c807SRodney W. Grimes { 572f789b261SWarner Losh HD_VCPIO *hd; 5734b88c807SRodney W. Grimes dev_t devminor; 5744b88c807SRodney W. Grimes dev_t devmajor; 575f789b261SWarner Losh int nsz; 5764b88c807SRodney W. Grimes 5774b88c807SRodney W. Grimes /* 5784b88c807SRodney W. Grimes * during the id phase it was determined if we were using CRC, use the 5794b88c807SRodney W. Grimes * proper id routine. 5804b88c807SRodney W. Grimes */ 5814b88c807SRodney W. Grimes if (docrc) { 5824b88c807SRodney W. Grimes if (crc_id(buf, sizeof(HD_VCPIO)) < 0) 5834b88c807SRodney W. Grimes return(-1); 5844b88c807SRodney W. Grimes } else { 5854b88c807SRodney W. Grimes if (vcpio_id(buf, sizeof(HD_VCPIO)) < 0) 5864b88c807SRodney W. Grimes return(-1); 5874b88c807SRodney W. Grimes } 5884b88c807SRodney W. Grimes 5894b88c807SRodney W. Grimes hd = (HD_VCPIO *)buf; 5904b88c807SRodney W. Grimes arcn->pad = 0L; 5914b88c807SRodney W. Grimes 5924b88c807SRodney W. Grimes /* 5934b88c807SRodney W. Grimes * extract the hex ascii fields from the header 5944b88c807SRodney W. Grimes */ 5954b88c807SRodney W. Grimes arcn->sb.st_ino = (ino_t)asc_ul(hd->c_ino, sizeof(hd->c_ino), HEX); 5964b88c807SRodney W. Grimes arcn->sb.st_mode = (mode_t)asc_ul(hd->c_mode, sizeof(hd->c_mode), HEX); 5974b88c807SRodney W. Grimes arcn->sb.st_uid = (uid_t)asc_ul(hd->c_uid, sizeof(hd->c_uid), HEX); 5984b88c807SRodney W. Grimes arcn->sb.st_gid = (gid_t)asc_ul(hd->c_gid, sizeof(hd->c_gid), HEX); 5992ad45bbeSMatthew Dillon #ifdef NET2_STAT 6004b88c807SRodney W. Grimes arcn->sb.st_mtime = (time_t)asc_ul(hd->c_mtime,sizeof(hd->c_mtime),HEX); 6012ad45bbeSMatthew Dillon #else 6022ad45bbeSMatthew Dillon arcn->sb.st_mtime = (time_t)asc_uqd(hd->c_mtime,sizeof(hd->c_mtime),HEX); 6032ad45bbeSMatthew Dillon #endif 6044b88c807SRodney W. Grimes arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime; 6054b88c807SRodney W. Grimes #ifdef NET2_STAT 6064b88c807SRodney W. Grimes arcn->sb.st_size = (off_t)asc_ul(hd->c_filesize, 6074b88c807SRodney W. Grimes sizeof(hd->c_filesize), HEX); 6084b88c807SRodney W. Grimes #else 6094b88c807SRodney W. Grimes arcn->sb.st_size = (off_t)asc_uqd(hd->c_filesize, 6104b88c807SRodney W. Grimes sizeof(hd->c_filesize), HEX); 6114b88c807SRodney W. Grimes #endif 6124b88c807SRodney W. Grimes arcn->sb.st_nlink = (nlink_t)asc_ul(hd->c_nlink, sizeof(hd->c_nlink), 6134b88c807SRodney W. Grimes HEX); 6144b88c807SRodney W. Grimes devmajor = (dev_t)asc_ul(hd->c_maj, sizeof(hd->c_maj), HEX); 6154b88c807SRodney W. Grimes devminor = (dev_t)asc_ul(hd->c_min, sizeof(hd->c_min), HEX); 6164b88c807SRodney W. Grimes arcn->sb.st_dev = TODEV(devmajor, devminor); 6174b88c807SRodney W. Grimes devmajor = (dev_t)asc_ul(hd->c_rmaj, sizeof(hd->c_maj), HEX); 6184b88c807SRodney W. Grimes devminor = (dev_t)asc_ul(hd->c_rmin, sizeof(hd->c_min), HEX); 6194b88c807SRodney W. Grimes arcn->sb.st_rdev = TODEV(devmajor, devminor); 6204b88c807SRodney W. Grimes arcn->crc = asc_ul(hd->c_chksum, sizeof(hd->c_chksum), HEX); 6214b88c807SRodney W. Grimes 6224b88c807SRodney W. Grimes /* 6234b88c807SRodney W. Grimes * check the length of the file name, if ok read it in, return -1 if 6244b88c807SRodney W. Grimes * bogus 6254b88c807SRodney W. Grimes */ 6264b88c807SRodney W. Grimes if ((nsz = (int)asc_ul(hd->c_namesize,sizeof(hd->c_namesize),HEX)) < 2) 6274b88c807SRodney W. Grimes return(-1); 6284b88c807SRodney W. Grimes arcn->nlen = nsz - 1; 6294b88c807SRodney W. Grimes if (rd_nm(arcn, nsz) < 0) 6304b88c807SRodney W. Grimes return(-1); 6314b88c807SRodney W. Grimes 6324b88c807SRodney W. Grimes /* 6334b88c807SRodney W. Grimes * skip padding. header + filename is aligned to 4 byte boundries 6344b88c807SRodney W. Grimes */ 6354b88c807SRodney W. Grimes if (rd_skip((off_t)(VCPIO_PAD(sizeof(HD_VCPIO) + nsz))) < 0) 6364b88c807SRodney W. Grimes return(-1); 6374b88c807SRodney W. Grimes 6384b88c807SRodney W. Grimes /* 6394b88c807SRodney W. Grimes * if not a link (or a file with no data), calculate pad size (for 6404b88c807SRodney W. Grimes * padding which follows the file data), clear the link name and return 6414b88c807SRodney W. Grimes */ 6424b88c807SRodney W. Grimes if (((arcn->sb.st_mode&C_IFMT) != C_ISLNK)||(arcn->sb.st_size == 0)) { 6434b88c807SRodney W. Grimes /* 6444b88c807SRodney W. Grimes * we have a valid header (not a link) 6454b88c807SRodney W. Grimes */ 6464b88c807SRodney W. Grimes arcn->ln_nlen = 0; 6474b88c807SRodney W. Grimes arcn->ln_name[0] = '\0'; 6484b88c807SRodney W. Grimes arcn->pad = VCPIO_PAD(arcn->sb.st_size); 6494b88c807SRodney W. Grimes return(com_rd(arcn)); 6504b88c807SRodney W. Grimes } 6514b88c807SRodney W. Grimes 6524b88c807SRodney W. Grimes /* 6534b88c807SRodney W. Grimes * read in the link name and skip over the padding 6544b88c807SRodney W. Grimes */ 6554b88c807SRodney W. Grimes if ((rd_ln_nm(arcn) < 0) || 6564b88c807SRodney W. Grimes (rd_skip((off_t)(VCPIO_PAD(arcn->sb.st_size))) < 0)) 6574b88c807SRodney W. Grimes return(-1); 6584b88c807SRodney W. Grimes 6594b88c807SRodney W. Grimes /* 6604b88c807SRodney W. Grimes * we have a valid header (with a link) 6614b88c807SRodney W. Grimes */ 6624b88c807SRodney W. Grimes return(com_rd(arcn)); 6634b88c807SRodney W. Grimes } 6644b88c807SRodney W. Grimes 6654b88c807SRodney W. Grimes /* 6664b88c807SRodney W. Grimes * vcpio_endrd() 6674b88c807SRodney W. Grimes * no cleanup needed here, just return size of the trailer (for append) 6684b88c807SRodney W. Grimes * Return: 6694b88c807SRodney W. Grimes * size of trailer header in this format 6704b88c807SRodney W. Grimes */ 6714b88c807SRodney W. Grimes 6724b88c807SRodney W. Grimes off_t 6734b88c807SRodney W. Grimes vcpio_endrd(void) 6744b88c807SRodney W. Grimes { 6754b88c807SRodney W. Grimes return((off_t)(sizeof(HD_VCPIO) + sizeof(TRAILER) + 6764b88c807SRodney W. Grimes (VCPIO_PAD(sizeof(HD_VCPIO) + sizeof(TRAILER))))); 6774b88c807SRodney W. Grimes } 6784b88c807SRodney W. Grimes 6794b88c807SRodney W. Grimes /* 6804b88c807SRodney W. Grimes * crc_stwr() 6814b88c807SRodney W. Grimes * start up the device mapping table, enable crc file calculation 6824b88c807SRodney W. Grimes * Return: 6834b88c807SRodney W. Grimes * 0 if ok, -1 otherwise (what dev_start() returns) 6844b88c807SRodney W. Grimes */ 6854b88c807SRodney W. Grimes 6864b88c807SRodney W. Grimes int 6874b88c807SRodney W. Grimes crc_stwr(void) 6884b88c807SRodney W. Grimes { 6894b88c807SRodney W. Grimes docrc = 1; 6904b88c807SRodney W. Grimes return(dev_start()); 6914b88c807SRodney W. Grimes } 6924b88c807SRodney W. Grimes 6934b88c807SRodney W. Grimes /* 6944b88c807SRodney W. Grimes * vcpio_wr() 6954b88c807SRodney W. Grimes * copy the data in the ARCHD to buffer in system VR4 cpio 6964b88c807SRodney W. Grimes * (with/without crc) format. 6974b88c807SRodney W. Grimes * Return 6984b88c807SRodney W. Grimes * 0 if file has data to be written after the header, 1 if file has 6994b88c807SRodney W. Grimes * NO data to write after the header, -1 if archive write failed 7004b88c807SRodney W. Grimes */ 7014b88c807SRodney W. Grimes 7024b88c807SRodney W. Grimes int 703f789b261SWarner Losh vcpio_wr(ARCHD *arcn) 7044b88c807SRodney W. Grimes { 705f789b261SWarner Losh HD_VCPIO *hd; 7064b88c807SRodney W. Grimes unsigned int nsz; 7074b88c807SRodney W. Grimes char hdblk[sizeof(HD_VCPIO)]; 7084b88c807SRodney W. Grimes 7094b88c807SRodney W. Grimes /* 7104b88c807SRodney W. Grimes * check and repair truncated device and inode fields in the cpio 7114b88c807SRodney W. Grimes * header 7124b88c807SRodney W. Grimes */ 7134b88c807SRodney W. Grimes if (map_dev(arcn, (u_long)VCPIO_MASK, (u_long)VCPIO_MASK) < 0) 7144b88c807SRodney W. Grimes return(-1); 7154b88c807SRodney W. Grimes nsz = arcn->nlen + 1; 7164b88c807SRodney W. Grimes hd = (HD_VCPIO *)hdblk; 7174b88c807SRodney W. Grimes if ((arcn->type != PAX_BLK) && (arcn->type != PAX_CHR)) 7184b88c807SRodney W. Grimes arcn->sb.st_rdev = 0; 7194b88c807SRodney W. Grimes 7204b88c807SRodney W. Grimes /* 7214b88c807SRodney W. Grimes * add the proper magic value depending whether we were asked for 7224b88c807SRodney W. Grimes * file data crc's, and the crc if needed. 7234b88c807SRodney W. Grimes */ 7244b88c807SRodney W. Grimes if (docrc) { 7254b88c807SRodney W. Grimes if (ul_asc((u_long)VCMAGIC, hd->c_magic, sizeof(hd->c_magic), 7264b88c807SRodney W. Grimes OCT) || 7274b88c807SRodney W. Grimes ul_asc((u_long)arcn->crc,hd->c_chksum,sizeof(hd->c_chksum), 7284b88c807SRodney W. Grimes HEX)) 7294b88c807SRodney W. Grimes goto out; 7304b88c807SRodney W. Grimes } else { 7314b88c807SRodney W. Grimes if (ul_asc((u_long)VMAGIC, hd->c_magic, sizeof(hd->c_magic), 7324b88c807SRodney W. Grimes OCT) || 7334b88c807SRodney W. Grimes ul_asc((u_long)0L, hd->c_chksum, sizeof(hd->c_chksum),HEX)) 7344b88c807SRodney W. Grimes goto out; 7354b88c807SRodney W. Grimes } 7364b88c807SRodney W. Grimes 7374b88c807SRodney W. Grimes switch(arcn->type) { 7384b88c807SRodney W. Grimes case PAX_CTG: 7394b88c807SRodney W. Grimes case PAX_REG: 7404b88c807SRodney W. Grimes case PAX_HRG: 7414b88c807SRodney W. Grimes /* 7424b88c807SRodney W. Grimes * caller will copy file data to the archive. tell him how 7434b88c807SRodney W. Grimes * much to pad. 7444b88c807SRodney W. Grimes */ 7454b88c807SRodney W. Grimes arcn->pad = VCPIO_PAD(arcn->sb.st_size); 7464b88c807SRodney W. Grimes # ifdef NET2_STAT 7474b88c807SRodney W. Grimes if (ul_asc((u_long)arcn->sb.st_size, hd->c_filesize, 7484b88c807SRodney W. Grimes sizeof(hd->c_filesize), HEX)) { 7494b88c807SRodney W. Grimes # else 7504b88c807SRodney W. Grimes if (uqd_asc((u_quad_t)arcn->sb.st_size, hd->c_filesize, 7514b88c807SRodney W. Grimes sizeof(hd->c_filesize), HEX)) { 7524b88c807SRodney W. Grimes # endif 753778766feSKris Kennaway paxwarn(1,"File is too large for sv4cpio format %s", 7544b88c807SRodney W. Grimes arcn->org_name); 7554b88c807SRodney W. Grimes return(1); 7564b88c807SRodney W. Grimes } 7574b88c807SRodney W. Grimes break; 7584b88c807SRodney W. Grimes case PAX_SLK: 7594b88c807SRodney W. Grimes /* 7604b88c807SRodney W. Grimes * no file data for the caller to process, the file data has 7614b88c807SRodney W. Grimes * the size of the link 7624b88c807SRodney W. Grimes */ 7634b88c807SRodney W. Grimes arcn->pad = 0L; 7644b88c807SRodney W. Grimes if (ul_asc((u_long)arcn->ln_nlen, hd->c_filesize, 7654b88c807SRodney W. Grimes sizeof(hd->c_filesize), HEX)) 7664b88c807SRodney W. Grimes goto out; 7674b88c807SRodney W. Grimes break; 7684b88c807SRodney W. Grimes default: 7694b88c807SRodney W. Grimes /* 7704b88c807SRodney W. Grimes * no file data for the caller to process 7714b88c807SRodney W. Grimes */ 7724b88c807SRodney W. Grimes arcn->pad = 0L; 7734b88c807SRodney W. Grimes if (ul_asc((u_long)0L, hd->c_filesize, sizeof(hd->c_filesize), 7744b88c807SRodney W. Grimes HEX)) 7754b88c807SRodney W. Grimes goto out; 7764b88c807SRodney W. Grimes break; 7774b88c807SRodney W. Grimes } 7784b88c807SRodney W. Grimes 7794b88c807SRodney W. Grimes /* 7804b88c807SRodney W. Grimes * set the other fields in the header 7814b88c807SRodney W. Grimes */ 7824b88c807SRodney W. Grimes if (ul_asc((u_long)arcn->sb.st_ino, hd->c_ino, sizeof(hd->c_ino), 7834b88c807SRodney W. Grimes HEX) || 7844b88c807SRodney W. Grimes ul_asc((u_long)arcn->sb.st_mode, hd->c_mode, sizeof(hd->c_mode), 7854b88c807SRodney W. Grimes HEX) || 7864b88c807SRodney W. Grimes ul_asc((u_long)arcn->sb.st_uid, hd->c_uid, sizeof(hd->c_uid), 7874b88c807SRodney W. Grimes HEX) || 7884b88c807SRodney W. Grimes ul_asc((u_long)arcn->sb.st_gid, hd->c_gid, sizeof(hd->c_gid), 7894b88c807SRodney W. Grimes HEX) || 7904b88c807SRodney W. Grimes ul_asc((u_long)arcn->sb.st_mtime, hd->c_mtime, sizeof(hd->c_mtime), 7914b88c807SRodney W. Grimes HEX) || 7924b88c807SRodney W. Grimes ul_asc((u_long)arcn->sb.st_nlink, hd->c_nlink, sizeof(hd->c_nlink), 7934b88c807SRodney W. Grimes HEX) || 7944b88c807SRodney W. Grimes ul_asc((u_long)MAJOR(arcn->sb.st_dev),hd->c_maj, sizeof(hd->c_maj), 7954b88c807SRodney W. Grimes HEX) || 7964b88c807SRodney W. Grimes ul_asc((u_long)MINOR(arcn->sb.st_dev),hd->c_min, sizeof(hd->c_min), 7974b88c807SRodney W. Grimes HEX) || 7984b88c807SRodney W. Grimes ul_asc((u_long)MAJOR(arcn->sb.st_rdev),hd->c_rmaj,sizeof(hd->c_maj), 7994b88c807SRodney W. Grimes HEX) || 8004b88c807SRodney W. Grimes ul_asc((u_long)MINOR(arcn->sb.st_rdev),hd->c_rmin,sizeof(hd->c_min), 8014b88c807SRodney W. Grimes HEX) || 8024b88c807SRodney W. Grimes ul_asc((u_long)nsz, hd->c_namesize, sizeof(hd->c_namesize), HEX)) 8034b88c807SRodney W. Grimes goto out; 8044b88c807SRodney W. Grimes 8054b88c807SRodney W. Grimes /* 8064b88c807SRodney W. Grimes * write the header, the file name and padding as required. 8074b88c807SRodney W. Grimes */ 8084b88c807SRodney W. Grimes if ((wr_rdbuf(hdblk, (int)sizeof(HD_VCPIO)) < 0) || 8094b88c807SRodney W. Grimes (wr_rdbuf(arcn->name, (int)nsz) < 0) || 8104b88c807SRodney W. Grimes (wr_skip((off_t)(VCPIO_PAD(sizeof(HD_VCPIO) + nsz))) < 0)) { 811778766feSKris Kennaway paxwarn(1,"Could not write sv4cpio header for %s",arcn->org_name); 8124b88c807SRodney W. Grimes return(-1); 8134b88c807SRodney W. Grimes } 8144b88c807SRodney W. Grimes 8154b88c807SRodney W. Grimes /* 8164b88c807SRodney W. Grimes * if we have file data, tell the caller we are done, copy the file 8174b88c807SRodney W. Grimes */ 8184b88c807SRodney W. Grimes if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG) || 8194b88c807SRodney W. Grimes (arcn->type == PAX_HRG)) 8204b88c807SRodney W. Grimes return(0); 8214b88c807SRodney W. Grimes 8224b88c807SRodney W. Grimes /* 8234b88c807SRodney W. Grimes * if we are not a link, tell the caller we are done, go to next file 8244b88c807SRodney W. Grimes */ 8254b88c807SRodney W. Grimes if (arcn->type != PAX_SLK) 8264b88c807SRodney W. Grimes return(1); 8274b88c807SRodney W. Grimes 8284b88c807SRodney W. Grimes /* 8294b88c807SRodney W. Grimes * write the link name, tell the caller we are done. 8304b88c807SRodney W. Grimes */ 8314b88c807SRodney W. Grimes if ((wr_rdbuf(arcn->ln_name, arcn->ln_nlen) < 0) || 8324b88c807SRodney W. Grimes (wr_skip((off_t)(VCPIO_PAD(arcn->ln_nlen))) < 0)) { 833778766feSKris Kennaway paxwarn(1,"Could not write sv4cpio link name for %s", 8344b88c807SRodney W. Grimes arcn->org_name); 8354b88c807SRodney W. Grimes return(-1); 8364b88c807SRodney W. Grimes } 8374b88c807SRodney W. Grimes return(1); 8384b88c807SRodney W. Grimes 8394b88c807SRodney W. Grimes out: 8404b88c807SRodney W. Grimes /* 8414b88c807SRodney W. Grimes * header field is out of range 8424b88c807SRodney W. Grimes */ 843778766feSKris Kennaway paxwarn(1,"Sv4cpio header field is too small for file %s",arcn->org_name); 8444b88c807SRodney W. Grimes return(1); 8454b88c807SRodney W. Grimes } 8464b88c807SRodney W. Grimes 8474b88c807SRodney W. Grimes /* 8484b88c807SRodney W. Grimes * Routines common to the old binary header cpio 8494b88c807SRodney W. Grimes */ 8504b88c807SRodney W. Grimes 8514b88c807SRodney W. Grimes /* 8524b88c807SRodney W. Grimes * bcpio_id() 8534b88c807SRodney W. Grimes * determine if a block given to us is a old binary cpio header 8544b88c807SRodney W. Grimes * (with/without header byte swapping) 8554b88c807SRodney W. Grimes * Return: 8564b88c807SRodney W. Grimes * 0 if a valid header, -1 otherwise 8574b88c807SRodney W. Grimes */ 8584b88c807SRodney W. Grimes 8594b88c807SRodney W. Grimes int 8604b88c807SRodney W. Grimes bcpio_id(char *blk, int size) 8614b88c807SRodney W. Grimes { 8624b88c807SRodney W. Grimes if (size < sizeof(HD_BCPIO)) 8634b88c807SRodney W. Grimes return(-1); 8644b88c807SRodney W. Grimes 8654b88c807SRodney W. Grimes /* 8664b88c807SRodney W. Grimes * check both normal and byte swapped magic cookies 8674b88c807SRodney W. Grimes */ 8684b88c807SRodney W. Grimes if (((u_short)SHRT_EXT(blk)) == MAGIC) 8694b88c807SRodney W. Grimes return(0); 8704b88c807SRodney W. Grimes if (((u_short)RSHRT_EXT(blk)) == MAGIC) { 8714b88c807SRodney W. Grimes if (!swp_head) 8724b88c807SRodney W. Grimes ++swp_head; 8734b88c807SRodney W. Grimes return(0); 8744b88c807SRodney W. Grimes } 8754b88c807SRodney W. Grimes return(-1); 8764b88c807SRodney W. Grimes } 8774b88c807SRodney W. Grimes 8784b88c807SRodney W. Grimes /* 8794b88c807SRodney W. Grimes * bcpio_rd() 8804b88c807SRodney W. Grimes * determine if a buffer is a old binary archive entry. (it may have byte 8814b88c807SRodney W. Grimes * swapped header) convert and store the values in the ARCHD parameter. 8824b88c807SRodney W. Grimes * This is a very old header format and should not really be used. 8834b88c807SRodney W. Grimes * Return: 8844b88c807SRodney W. Grimes * 0 if a valid header, -1 otherwise. 8854b88c807SRodney W. Grimes */ 8864b88c807SRodney W. Grimes 8874b88c807SRodney W. Grimes int 888f789b261SWarner Losh bcpio_rd(ARCHD *arcn, char *buf) 8894b88c807SRodney W. Grimes { 890f789b261SWarner Losh HD_BCPIO *hd; 891f789b261SWarner Losh int nsz; 8924b88c807SRodney W. Grimes 8934b88c807SRodney W. Grimes /* 8944b88c807SRodney W. Grimes * check the header 8954b88c807SRodney W. Grimes */ 8964b88c807SRodney W. Grimes if (bcpio_id(buf, sizeof(HD_BCPIO)) < 0) 8974b88c807SRodney W. Grimes return(-1); 8984b88c807SRodney W. Grimes 8994b88c807SRodney W. Grimes arcn->pad = 0L; 9004b88c807SRodney W. Grimes hd = (HD_BCPIO *)buf; 9014b88c807SRodney W. Grimes if (swp_head) { 9024b88c807SRodney W. Grimes /* 90346be34b9SKris Kennaway * header has swapped bytes on 16 bit boundaries 9044b88c807SRodney W. Grimes */ 9054b88c807SRodney W. Grimes arcn->sb.st_dev = (dev_t)(RSHRT_EXT(hd->h_dev)); 9064b88c807SRodney W. Grimes arcn->sb.st_ino = (ino_t)(RSHRT_EXT(hd->h_ino)); 9074b88c807SRodney W. Grimes arcn->sb.st_mode = (mode_t)(RSHRT_EXT(hd->h_mode)); 9084b88c807SRodney W. Grimes arcn->sb.st_uid = (uid_t)(RSHRT_EXT(hd->h_uid)); 9094b88c807SRodney W. Grimes arcn->sb.st_gid = (gid_t)(RSHRT_EXT(hd->h_gid)); 9104b88c807SRodney W. Grimes arcn->sb.st_nlink = (nlink_t)(RSHRT_EXT(hd->h_nlink)); 9114b88c807SRodney W. Grimes arcn->sb.st_rdev = (dev_t)(RSHRT_EXT(hd->h_rdev)); 9124b88c807SRodney W. Grimes arcn->sb.st_mtime = (time_t)(RSHRT_EXT(hd->h_mtime_1)); 9134b88c807SRodney W. Grimes arcn->sb.st_mtime = (arcn->sb.st_mtime << 16) | 9144b88c807SRodney W. Grimes ((time_t)(RSHRT_EXT(hd->h_mtime_2))); 9154b88c807SRodney W. Grimes arcn->sb.st_size = (off_t)(RSHRT_EXT(hd->h_filesize_1)); 9164b88c807SRodney W. Grimes arcn->sb.st_size = (arcn->sb.st_size << 16) | 9174b88c807SRodney W. Grimes ((off_t)(RSHRT_EXT(hd->h_filesize_2))); 9184b88c807SRodney W. Grimes nsz = (int)(RSHRT_EXT(hd->h_namesize)); 9194b88c807SRodney W. Grimes } else { 9204b88c807SRodney W. Grimes arcn->sb.st_dev = (dev_t)(SHRT_EXT(hd->h_dev)); 9214b88c807SRodney W. Grimes arcn->sb.st_ino = (ino_t)(SHRT_EXT(hd->h_ino)); 9224b88c807SRodney W. Grimes arcn->sb.st_mode = (mode_t)(SHRT_EXT(hd->h_mode)); 9234b88c807SRodney W. Grimes arcn->sb.st_uid = (uid_t)(SHRT_EXT(hd->h_uid)); 9244b88c807SRodney W. Grimes arcn->sb.st_gid = (gid_t)(SHRT_EXT(hd->h_gid)); 9254b88c807SRodney W. Grimes arcn->sb.st_nlink = (nlink_t)(SHRT_EXT(hd->h_nlink)); 9264b88c807SRodney W. Grimes arcn->sb.st_rdev = (dev_t)(SHRT_EXT(hd->h_rdev)); 9274b88c807SRodney W. Grimes arcn->sb.st_mtime = (time_t)(SHRT_EXT(hd->h_mtime_1)); 9284b88c807SRodney W. Grimes arcn->sb.st_mtime = (arcn->sb.st_mtime << 16) | 9294b88c807SRodney W. Grimes ((time_t)(SHRT_EXT(hd->h_mtime_2))); 9304b88c807SRodney W. Grimes arcn->sb.st_size = (off_t)(SHRT_EXT(hd->h_filesize_1)); 9314b88c807SRodney W. Grimes arcn->sb.st_size = (arcn->sb.st_size << 16) | 9324b88c807SRodney W. Grimes ((off_t)(SHRT_EXT(hd->h_filesize_2))); 9334b88c807SRodney W. Grimes nsz = (int)(SHRT_EXT(hd->h_namesize)); 9344b88c807SRodney W. Grimes } 9354b88c807SRodney W. Grimes arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime; 9364b88c807SRodney W. Grimes 9374b88c807SRodney W. Grimes /* 9384b88c807SRodney W. Grimes * check the file name size, if bogus give up. otherwise read the file 9394b88c807SRodney W. Grimes * name 9404b88c807SRodney W. Grimes */ 9414b88c807SRodney W. Grimes if (nsz < 2) 9424b88c807SRodney W. Grimes return(-1); 9434b88c807SRodney W. Grimes arcn->nlen = nsz - 1; 9444b88c807SRodney W. Grimes if (rd_nm(arcn, nsz) < 0) 9454b88c807SRodney W. Grimes return(-1); 9464b88c807SRodney W. Grimes 9474b88c807SRodney W. Grimes /* 9484b88c807SRodney W. Grimes * header + file name are aligned to 2 byte boundries, skip if needed 9494b88c807SRodney W. Grimes */ 9504b88c807SRodney W. Grimes if (rd_skip((off_t)(BCPIO_PAD(sizeof(HD_BCPIO) + nsz))) < 0) 9514b88c807SRodney W. Grimes return(-1); 9524b88c807SRodney W. Grimes 9534b88c807SRodney W. Grimes /* 9544b88c807SRodney W. Grimes * if not a link (or a file with no data), calculate pad size (for 9554b88c807SRodney W. Grimes * padding which follows the file data), clear the link name and return 9564b88c807SRodney W. Grimes */ 9574b88c807SRodney W. Grimes if (((arcn->sb.st_mode & C_IFMT) != C_ISLNK)||(arcn->sb.st_size == 0)){ 9584b88c807SRodney W. Grimes /* 9594b88c807SRodney W. Grimes * we have a valid header (not a link) 9604b88c807SRodney W. Grimes */ 9614b88c807SRodney W. Grimes arcn->ln_nlen = 0; 9624b88c807SRodney W. Grimes arcn->ln_name[0] = '\0'; 9634b88c807SRodney W. Grimes arcn->pad = BCPIO_PAD(arcn->sb.st_size); 9644b88c807SRodney W. Grimes return(com_rd(arcn)); 9654b88c807SRodney W. Grimes } 9664b88c807SRodney W. Grimes 9674b88c807SRodney W. Grimes if ((rd_ln_nm(arcn) < 0) || 9684b88c807SRodney W. Grimes (rd_skip((off_t)(BCPIO_PAD(arcn->sb.st_size))) < 0)) 9694b88c807SRodney W. Grimes return(-1); 9704b88c807SRodney W. Grimes 9714b88c807SRodney W. Grimes /* 9724b88c807SRodney W. Grimes * we have a valid header (with a link) 9734b88c807SRodney W. Grimes */ 9744b88c807SRodney W. Grimes return(com_rd(arcn)); 9754b88c807SRodney W. Grimes } 9764b88c807SRodney W. Grimes 9774b88c807SRodney W. Grimes /* 9784b88c807SRodney W. Grimes * bcpio_endrd() 9794b88c807SRodney W. Grimes * no cleanup needed here, just return size of the trailer (for append) 9804b88c807SRodney W. Grimes * Return: 9814b88c807SRodney W. Grimes * size of trailer header in this format 9824b88c807SRodney W. Grimes */ 9834b88c807SRodney W. Grimes 9844b88c807SRodney W. Grimes off_t 9854b88c807SRodney W. Grimes bcpio_endrd(void) 9864b88c807SRodney W. Grimes { 9874b88c807SRodney W. Grimes return((off_t)(sizeof(HD_BCPIO) + sizeof(TRAILER) + 9884b88c807SRodney W. Grimes (BCPIO_PAD(sizeof(HD_BCPIO) + sizeof(TRAILER))))); 9894b88c807SRodney W. Grimes } 9904b88c807SRodney W. Grimes 9914b88c807SRodney W. Grimes /* 9924b88c807SRodney W. Grimes * bcpio_wr() 9934b88c807SRodney W. Grimes * copy the data in the ARCHD to buffer in old binary cpio format 9944b88c807SRodney W. Grimes * There is a real chance of field overflow with this critter. So we 9954b88c807SRodney W. Grimes * always check the conversion is ok. nobody in his their right mind 9964b88c807SRodney W. Grimes * should write an achive in this format... 9974b88c807SRodney W. Grimes * Return 9984b88c807SRodney W. Grimes * 0 if file has data to be written after the header, 1 if file has NO 9994b88c807SRodney W. Grimes * data to write after the header, -1 if archive write failed 10004b88c807SRodney W. Grimes */ 10014b88c807SRodney W. Grimes 10024b88c807SRodney W. Grimes int 1003f789b261SWarner Losh bcpio_wr(ARCHD *arcn) 10044b88c807SRodney W. Grimes { 1005f789b261SWarner Losh HD_BCPIO *hd; 1006f789b261SWarner Losh int nsz; 10074b88c807SRodney W. Grimes char hdblk[sizeof(HD_BCPIO)]; 10084b88c807SRodney W. Grimes off_t t_offt; 10094b88c807SRodney W. Grimes int t_int; 10104b88c807SRodney W. Grimes time_t t_timet; 10114b88c807SRodney W. Grimes 10124b88c807SRodney W. Grimes /* 10134b88c807SRodney W. Grimes * check and repair truncated device and inode fields in the cpio 10144b88c807SRodney W. Grimes * header 10154b88c807SRodney W. Grimes */ 10164b88c807SRodney W. Grimes if (map_dev(arcn, (u_long)BCPIO_MASK, (u_long)BCPIO_MASK) < 0) 10174b88c807SRodney W. Grimes return(-1); 10184b88c807SRodney W. Grimes 10194b88c807SRodney W. Grimes if ((arcn->type != PAX_BLK) && (arcn->type != PAX_CHR)) 10204b88c807SRodney W. Grimes arcn->sb.st_rdev = 0; 10214b88c807SRodney W. Grimes hd = (HD_BCPIO *)hdblk; 10224b88c807SRodney W. Grimes 10234b88c807SRodney W. Grimes switch(arcn->type) { 10244b88c807SRodney W. Grimes case PAX_CTG: 10254b88c807SRodney W. Grimes case PAX_REG: 10264b88c807SRodney W. Grimes case PAX_HRG: 10274b88c807SRodney W. Grimes /* 10284b88c807SRodney W. Grimes * caller will copy file data to the archive. tell him how 10294b88c807SRodney W. Grimes * much to pad. 10304b88c807SRodney W. Grimes */ 10314b88c807SRodney W. Grimes arcn->pad = BCPIO_PAD(arcn->sb.st_size); 10324b88c807SRodney W. Grimes hd->h_filesize_1[0] = CHR_WR_0(arcn->sb.st_size); 10334b88c807SRodney W. Grimes hd->h_filesize_1[1] = CHR_WR_1(arcn->sb.st_size); 10344b88c807SRodney W. Grimes hd->h_filesize_2[0] = CHR_WR_2(arcn->sb.st_size); 10354b88c807SRodney W. Grimes hd->h_filesize_2[1] = CHR_WR_3(arcn->sb.st_size); 10364b88c807SRodney W. Grimes t_offt = (off_t)(SHRT_EXT(hd->h_filesize_1)); 10374b88c807SRodney W. Grimes t_offt = (t_offt<<16) | ((off_t)(SHRT_EXT(hd->h_filesize_2))); 10384b88c807SRodney W. Grimes if (arcn->sb.st_size != t_offt) { 1039778766feSKris Kennaway paxwarn(1,"File is too large for bcpio format %s", 10404b88c807SRodney W. Grimes arcn->org_name); 10414b88c807SRodney W. Grimes return(1); 10424b88c807SRodney W. Grimes } 10434b88c807SRodney W. Grimes break; 10444b88c807SRodney W. Grimes case PAX_SLK: 10454b88c807SRodney W. Grimes /* 10464b88c807SRodney W. Grimes * no file data for the caller to process, the file data has 10474b88c807SRodney W. Grimes * the size of the link 10484b88c807SRodney W. Grimes */ 10494b88c807SRodney W. Grimes arcn->pad = 0L; 10504b88c807SRodney W. Grimes hd->h_filesize_1[0] = CHR_WR_0(arcn->ln_nlen); 10514b88c807SRodney W. Grimes hd->h_filesize_1[1] = CHR_WR_1(arcn->ln_nlen); 10524b88c807SRodney W. Grimes hd->h_filesize_2[0] = CHR_WR_2(arcn->ln_nlen); 10534b88c807SRodney W. Grimes hd->h_filesize_2[1] = CHR_WR_3(arcn->ln_nlen); 10544b88c807SRodney W. Grimes t_int = (int)(SHRT_EXT(hd->h_filesize_1)); 10554b88c807SRodney W. Grimes t_int = (t_int << 16) | ((int)(SHRT_EXT(hd->h_filesize_2))); 10564b88c807SRodney W. Grimes if (arcn->ln_nlen != t_int) 10574b88c807SRodney W. Grimes goto out; 10584b88c807SRodney W. Grimes break; 10594b88c807SRodney W. Grimes default: 10604b88c807SRodney W. Grimes /* 10614b88c807SRodney W. Grimes * no file data for the caller to process 10624b88c807SRodney W. Grimes */ 10634b88c807SRodney W. Grimes arcn->pad = 0L; 10644b88c807SRodney W. Grimes hd->h_filesize_1[0] = (char)0; 10654b88c807SRodney W. Grimes hd->h_filesize_1[1] = (char)0; 10664b88c807SRodney W. Grimes hd->h_filesize_2[0] = (char)0; 10674b88c807SRodney W. Grimes hd->h_filesize_2[1] = (char)0; 10684b88c807SRodney W. Grimes break; 10694b88c807SRodney W. Grimes } 10704b88c807SRodney W. Grimes 10714b88c807SRodney W. Grimes /* 10724b88c807SRodney W. Grimes * build up the rest of the fields 10734b88c807SRodney W. Grimes */ 10744b88c807SRodney W. Grimes hd->h_magic[0] = CHR_WR_2(MAGIC); 10754b88c807SRodney W. Grimes hd->h_magic[1] = CHR_WR_3(MAGIC); 10764b88c807SRodney W. Grimes hd->h_dev[0] = CHR_WR_2(arcn->sb.st_dev); 10774b88c807SRodney W. Grimes hd->h_dev[1] = CHR_WR_3(arcn->sb.st_dev); 10784b88c807SRodney W. Grimes if (arcn->sb.st_dev != (dev_t)(SHRT_EXT(hd->h_dev))) 10794b88c807SRodney W. Grimes goto out; 10804b88c807SRodney W. Grimes hd->h_ino[0] = CHR_WR_2(arcn->sb.st_ino); 10814b88c807SRodney W. Grimes hd->h_ino[1] = CHR_WR_3(arcn->sb.st_ino); 10824b88c807SRodney W. Grimes if (arcn->sb.st_ino != (ino_t)(SHRT_EXT(hd->h_ino))) 10834b88c807SRodney W. Grimes goto out; 10844b88c807SRodney W. Grimes hd->h_mode[0] = CHR_WR_2(arcn->sb.st_mode); 10854b88c807SRodney W. Grimes hd->h_mode[1] = CHR_WR_3(arcn->sb.st_mode); 10864b88c807SRodney W. Grimes if (arcn->sb.st_mode != (mode_t)(SHRT_EXT(hd->h_mode))) 10874b88c807SRodney W. Grimes goto out; 10884b88c807SRodney W. Grimes hd->h_uid[0] = CHR_WR_2(arcn->sb.st_uid); 10894b88c807SRodney W. Grimes hd->h_uid[1] = CHR_WR_3(arcn->sb.st_uid); 10904b88c807SRodney W. Grimes if (arcn->sb.st_uid != (uid_t)(SHRT_EXT(hd->h_uid))) 10914b88c807SRodney W. Grimes goto out; 10924b88c807SRodney W. Grimes hd->h_gid[0] = CHR_WR_2(arcn->sb.st_gid); 10934b88c807SRodney W. Grimes hd->h_gid[1] = CHR_WR_3(arcn->sb.st_gid); 10944b88c807SRodney W. Grimes if (arcn->sb.st_gid != (gid_t)(SHRT_EXT(hd->h_gid))) 10954b88c807SRodney W. Grimes goto out; 10964b88c807SRodney W. Grimes hd->h_nlink[0] = CHR_WR_2(arcn->sb.st_nlink); 10974b88c807SRodney W. Grimes hd->h_nlink[1] = CHR_WR_3(arcn->sb.st_nlink); 10984b88c807SRodney W. Grimes if (arcn->sb.st_nlink != (nlink_t)(SHRT_EXT(hd->h_nlink))) 10994b88c807SRodney W. Grimes goto out; 11004b88c807SRodney W. Grimes hd->h_rdev[0] = CHR_WR_2(arcn->sb.st_rdev); 11014b88c807SRodney W. Grimes hd->h_rdev[1] = CHR_WR_3(arcn->sb.st_rdev); 11024b88c807SRodney W. Grimes if (arcn->sb.st_rdev != (dev_t)(SHRT_EXT(hd->h_rdev))) 11034b88c807SRodney W. Grimes goto out; 11044b88c807SRodney W. Grimes hd->h_mtime_1[0] = CHR_WR_0(arcn->sb.st_mtime); 11054b88c807SRodney W. Grimes hd->h_mtime_1[1] = CHR_WR_1(arcn->sb.st_mtime); 11064b88c807SRodney W. Grimes hd->h_mtime_2[0] = CHR_WR_2(arcn->sb.st_mtime); 11074b88c807SRodney W. Grimes hd->h_mtime_2[1] = CHR_WR_3(arcn->sb.st_mtime); 11084b88c807SRodney W. Grimes t_timet = (time_t)(SHRT_EXT(hd->h_mtime_1)); 11094b88c807SRodney W. Grimes t_timet = (t_timet << 16) | ((time_t)(SHRT_EXT(hd->h_mtime_2))); 11104b88c807SRodney W. Grimes if (arcn->sb.st_mtime != t_timet) 11114b88c807SRodney W. Grimes goto out; 11124b88c807SRodney W. Grimes nsz = arcn->nlen + 1; 11134b88c807SRodney W. Grimes hd->h_namesize[0] = CHR_WR_2(nsz); 11144b88c807SRodney W. Grimes hd->h_namesize[1] = CHR_WR_3(nsz); 11154b88c807SRodney W. Grimes if (nsz != (int)(SHRT_EXT(hd->h_namesize))) 11164b88c807SRodney W. Grimes goto out; 11174b88c807SRodney W. Grimes 11184b88c807SRodney W. Grimes /* 11194b88c807SRodney W. Grimes * write the header, the file name and padding as required. 11204b88c807SRodney W. Grimes */ 11214b88c807SRodney W. Grimes if ((wr_rdbuf(hdblk, (int)sizeof(HD_BCPIO)) < 0) || 11224b88c807SRodney W. Grimes (wr_rdbuf(arcn->name, nsz) < 0) || 11234b88c807SRodney W. Grimes (wr_skip((off_t)(BCPIO_PAD(sizeof(HD_BCPIO) + nsz))) < 0)) { 1124778766feSKris Kennaway paxwarn(1, "Could not write bcpio header for %s", arcn->org_name); 11254b88c807SRodney W. Grimes return(-1); 11264b88c807SRodney W. Grimes } 11274b88c807SRodney W. Grimes 11284b88c807SRodney W. Grimes /* 11294b88c807SRodney W. Grimes * if we have file data, tell the caller we are done 11304b88c807SRodney W. Grimes */ 11314b88c807SRodney W. Grimes if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG) || 11324b88c807SRodney W. Grimes (arcn->type == PAX_HRG)) 11334b88c807SRodney W. Grimes return(0); 11344b88c807SRodney W. Grimes 11354b88c807SRodney W. Grimes /* 11364b88c807SRodney W. Grimes * if we are not a link, tell the caller we are done, go to next file 11374b88c807SRodney W. Grimes */ 11384b88c807SRodney W. Grimes if (arcn->type != PAX_SLK) 11394b88c807SRodney W. Grimes return(1); 11404b88c807SRodney W. Grimes 11414b88c807SRodney W. Grimes /* 11424b88c807SRodney W. Grimes * write the link name, tell the caller we are done. 11434b88c807SRodney W. Grimes */ 11444b88c807SRodney W. Grimes if ((wr_rdbuf(arcn->ln_name, arcn->ln_nlen) < 0) || 11454b88c807SRodney W. Grimes (wr_skip((off_t)(BCPIO_PAD(arcn->ln_nlen))) < 0)) { 1146778766feSKris Kennaway paxwarn(1,"Could not write bcpio link name for %s",arcn->org_name); 11474b88c807SRodney W. Grimes return(-1); 11484b88c807SRodney W. Grimes } 11494b88c807SRodney W. Grimes return(1); 11504b88c807SRodney W. Grimes 11514b88c807SRodney W. Grimes out: 11524b88c807SRodney W. Grimes /* 11534b88c807SRodney W. Grimes * header field is out of range 11544b88c807SRodney W. Grimes */ 1155778766feSKris Kennaway paxwarn(1,"Bcpio header field is too small for file %s", arcn->org_name); 11564b88c807SRodney W. Grimes return(1); 11574b88c807SRodney W. Grimes } 1158