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