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 #include <sys/types.h> 374b88c807SRodney W. Grimes #include <sys/time.h> 384b88c807SRodney W. Grimes #include <sys/stat.h> 394b88c807SRodney W. Grimes #include <string.h> 405b94264cSTim J. Robbins #include <stdint.h> 414b88c807SRodney W. Grimes #include <stdio.h> 424b88c807SRodney W. Grimes #include "pax.h" 434b88c807SRodney W. Grimes #include "cpio.h" 444b88c807SRodney W. Grimes #include "extern.h" 454b88c807SRodney W. Grimes 46f789b261SWarner Losh static int rd_nm(ARCHD *, int); 47f789b261SWarner Losh static int rd_ln_nm(ARCHD *); 48f789b261SWarner Losh static int com_rd(ARCHD *); 494b88c807SRodney W. Grimes 504b88c807SRodney W. Grimes /* 514b88c807SRodney W. Grimes * Routines which support the different cpio versions 524b88c807SRodney W. Grimes */ 534b88c807SRodney W. Grimes 544b88c807SRodney W. Grimes static int swp_head; /* binary cpio header byte swap */ 554b88c807SRodney W. Grimes 564b88c807SRodney W. Grimes /* 574b88c807SRodney W. Grimes * Routines common to all versions of cpio 584b88c807SRodney W. Grimes */ 594b88c807SRodney W. Grimes 604b88c807SRodney W. Grimes /* 614b88c807SRodney W. Grimes * cpio_strd() 624b88c807SRodney W. Grimes * Fire up the hard link detection code 634b88c807SRodney W. Grimes * Return: 644b88c807SRodney W. Grimes * 0 if ok -1 otherwise (the return values of lnk_start()) 654b88c807SRodney W. Grimes */ 664b88c807SRodney W. Grimes 674b88c807SRodney W. Grimes int 684b88c807SRodney W. Grimes cpio_strd(void) 694b88c807SRodney W. Grimes { 704b88c807SRodney W. Grimes return(lnk_start()); 714b88c807SRodney W. Grimes } 724b88c807SRodney W. Grimes 734b88c807SRodney W. Grimes /* 744b88c807SRodney W. Grimes * cpio_trail() 754b88c807SRodney W. Grimes * Called to determine if a header block is a valid trailer. We are 764b88c807SRodney W. Grimes * passed the block, the in_sync flag (which tells us we are in resync 774b88c807SRodney W. Grimes * mode; looking for a valid header), and cnt (which starts at zero) 784b88c807SRodney W. Grimes * which is used to count the number of empty blocks we have seen so far. 794b88c807SRodney W. Grimes * Return: 804b88c807SRodney W. Grimes * 0 if a valid trailer, -1 if not a valid trailer, 814b88c807SRodney W. Grimes */ 824b88c807SRodney W. Grimes 834b88c807SRodney W. Grimes int 84f789b261SWarner Losh cpio_trail(ARCHD *arcn) 854b88c807SRodney W. Grimes { 864b88c807SRodney W. Grimes /* 874b88c807SRodney W. Grimes * look for trailer id in file we are about to process 884b88c807SRodney W. Grimes */ 894b88c807SRodney W. Grimes if ((strcmp(arcn->name, TRAILER) == 0) && (arcn->sb.st_size == 0)) 904b88c807SRodney W. Grimes return(0); 914b88c807SRodney W. Grimes return(-1); 924b88c807SRodney W. Grimes } 934b88c807SRodney W. Grimes 944b88c807SRodney W. Grimes /* 954b88c807SRodney W. Grimes * com_rd() 964b88c807SRodney W. Grimes * operations common to all cpio read functions. 974b88c807SRodney W. Grimes * Return: 984b88c807SRodney W. Grimes * 0 994b88c807SRodney W. Grimes */ 1004b88c807SRodney W. Grimes 1014b88c807SRodney W. Grimes static int 102f789b261SWarner Losh com_rd(ARCHD *arcn) 1034b88c807SRodney W. Grimes { 1044b88c807SRodney W. Grimes arcn->skip = 0; 1054b88c807SRodney W. Grimes arcn->pat = NULL; 1064b88c807SRodney W. Grimes arcn->org_name = arcn->name; 1074b88c807SRodney W. Grimes switch(arcn->sb.st_mode & C_IFMT) { 1084b88c807SRodney W. Grimes case C_ISFIFO: 1094b88c807SRodney W. Grimes arcn->type = PAX_FIF; 1104b88c807SRodney W. Grimes break; 1114b88c807SRodney W. Grimes case C_ISDIR: 1124b88c807SRodney W. Grimes arcn->type = PAX_DIR; 1134b88c807SRodney W. Grimes break; 1144b88c807SRodney W. Grimes case C_ISBLK: 1154b88c807SRodney W. Grimes arcn->type = PAX_BLK; 1164b88c807SRodney W. Grimes break; 1174b88c807SRodney W. Grimes case C_ISCHR: 1184b88c807SRodney W. Grimes arcn->type = PAX_CHR; 1194b88c807SRodney W. Grimes break; 1204b88c807SRodney W. Grimes case C_ISLNK: 1214b88c807SRodney W. Grimes arcn->type = PAX_SLK; 1224b88c807SRodney W. Grimes break; 1234b88c807SRodney W. Grimes case C_ISOCK: 1244b88c807SRodney W. Grimes arcn->type = PAX_SCK; 1254b88c807SRodney W. Grimes break; 1264b88c807SRodney W. Grimes case C_ISCTG: 1274b88c807SRodney W. Grimes case C_ISREG: 1284b88c807SRodney W. Grimes default: 1294b88c807SRodney W. Grimes /* 1304b88c807SRodney W. Grimes * we have file data, set up skip (pad is set in the format 1314b88c807SRodney W. Grimes * specific sections) 1324b88c807SRodney W. Grimes */ 1334b88c807SRodney W. Grimes arcn->sb.st_mode = (arcn->sb.st_mode & 0xfff) | C_ISREG; 1344b88c807SRodney W. Grimes arcn->type = PAX_REG; 1354b88c807SRodney W. Grimes arcn->skip = arcn->sb.st_size; 1364b88c807SRodney W. Grimes break; 1374b88c807SRodney W. Grimes } 1384b88c807SRodney W. Grimes if (chk_lnk(arcn) < 0) 1394b88c807SRodney W. Grimes return(-1); 1404b88c807SRodney W. Grimes return(0); 1414b88c807SRodney W. Grimes } 1424b88c807SRodney W. Grimes 1434b88c807SRodney W. Grimes /* 1440266a5d6SDag-Erling Smørgrav * cpio_endwr() 1454b88c807SRodney W. Grimes * write the special file with the name trailer in the proper format 1464b88c807SRodney W. Grimes * Return: 1474b88c807SRodney W. Grimes * result of the write of the trailer from the cpio specific write func 1484b88c807SRodney W. Grimes */ 1494b88c807SRodney W. Grimes 1504b88c807SRodney W. Grimes int 1514b88c807SRodney W. Grimes cpio_endwr(void) 1524b88c807SRodney W. Grimes { 1534b88c807SRodney W. Grimes ARCHD last; 1544b88c807SRodney W. Grimes 1554b88c807SRodney W. Grimes /* 1564b88c807SRodney W. Grimes * create a trailer request and call the proper format write function 1574b88c807SRodney W. Grimes */ 158778766feSKris Kennaway memset(&last, 0, sizeof(last)); 1594b88c807SRodney W. Grimes last.nlen = sizeof(TRAILER) - 1; 1604b88c807SRodney W. Grimes last.type = PAX_REG; 1614b88c807SRodney W. Grimes last.sb.st_nlink = 1; 1624b88c807SRodney W. Grimes (void)strcpy(last.name, TRAILER); 1634b88c807SRodney W. Grimes return((*frmt->wr)(&last)); 1644b88c807SRodney W. Grimes } 1654b88c807SRodney W. Grimes 1664b88c807SRodney W. Grimes /* 1674b88c807SRodney W. Grimes * rd_nam() 1684b88c807SRodney W. Grimes * read in the file name which follows the cpio header 1694b88c807SRodney W. Grimes * Return: 1704b88c807SRodney W. Grimes * 0 if ok, -1 otherwise 1714b88c807SRodney W. Grimes */ 1724b88c807SRodney W. Grimes 1734b88c807SRodney W. Grimes static int 174f789b261SWarner Losh rd_nm(ARCHD *arcn, int nsz) 1754b88c807SRodney W. Grimes { 1764b88c807SRodney W. Grimes /* 1774b88c807SRodney W. Grimes * do not even try bogus values 1784b88c807SRodney W. Grimes */ 179cee22cbdSDavid E. O'Brien if ((nsz == 0) || (nsz > (int)sizeof(arcn->name))) { 180778766feSKris Kennaway paxwarn(1, "Cpio file name length %d is out of range", nsz); 1814b88c807SRodney W. Grimes return(-1); 1824b88c807SRodney W. Grimes } 1834b88c807SRodney W. Grimes 1844b88c807SRodney W. Grimes /* 1854b88c807SRodney W. Grimes * read the name and make sure it is not empty and is \0 terminated 1864b88c807SRodney W. Grimes */ 1874b88c807SRodney W. Grimes if ((rd_wrbuf(arcn->name,nsz) != nsz) || (arcn->name[nsz-1] != '\0') || 1884b88c807SRodney W. Grimes (arcn->name[0] == '\0')) { 189778766feSKris Kennaway paxwarn(1, "Cpio file name in header is corrupted"); 1904b88c807SRodney W. Grimes return(-1); 1914b88c807SRodney W. Grimes } 1924b88c807SRodney W. Grimes return(0); 1934b88c807SRodney W. Grimes } 1944b88c807SRodney W. Grimes 1954b88c807SRodney W. Grimes /* 1964b88c807SRodney W. Grimes * rd_ln_nm() 1974b88c807SRodney W. Grimes * read in the link name for a file with links. The link name is stored 1984b88c807SRodney W. Grimes * like file data (and is NOT \0 terminated!) 1994b88c807SRodney W. Grimes * Return: 2004b88c807SRodney W. Grimes * 0 if ok, -1 otherwise 2014b88c807SRodney W. Grimes */ 2024b88c807SRodney W. Grimes 2034b88c807SRodney W. Grimes static int 204f789b261SWarner Losh rd_ln_nm(ARCHD *arcn) 2054b88c807SRodney W. Grimes { 2064b88c807SRodney W. Grimes /* 2074b88c807SRodney W. Grimes * check the length specified for bogus values 2084b88c807SRodney W. Grimes */ 2094b88c807SRodney W. Grimes if ((arcn->sb.st_size == 0) || 21040feca3aSMark Murray ((size_t)arcn->sb.st_size >= sizeof(arcn->ln_name))) { 2115b94264cSTim J. Robbins paxwarn(1, "Cpio link name length is invalid: %ju", 2125b94264cSTim J. Robbins (uintmax_t)arcn->sb.st_size); 2134b88c807SRodney W. Grimes return(-1); 2144b88c807SRodney W. Grimes } 2154b88c807SRodney W. Grimes 2164b88c807SRodney W. Grimes /* 2174b88c807SRodney W. Grimes * read in the link name and \0 terminate it 2184b88c807SRodney W. Grimes */ 2194b88c807SRodney W. Grimes if (rd_wrbuf(arcn->ln_name, (int)arcn->sb.st_size) != 2204b88c807SRodney W. Grimes (int)arcn->sb.st_size) { 221778766feSKris Kennaway paxwarn(1, "Cpio link name read error"); 2224b88c807SRodney W. Grimes return(-1); 2234b88c807SRodney W. Grimes } 2244b88c807SRodney W. Grimes arcn->ln_nlen = arcn->sb.st_size; 2254b88c807SRodney W. Grimes arcn->ln_name[arcn->ln_nlen] = '\0'; 2264b88c807SRodney W. Grimes 2274b88c807SRodney W. Grimes /* 2284b88c807SRodney W. Grimes * watch out for those empty link names 2294b88c807SRodney W. Grimes */ 2304b88c807SRodney W. Grimes if (arcn->ln_name[0] == '\0') { 231778766feSKris Kennaway paxwarn(1, "Cpio link name is corrupt"); 2324b88c807SRodney W. Grimes return(-1); 2334b88c807SRodney W. Grimes } 2344b88c807SRodney W. Grimes return(0); 2354b88c807SRodney W. Grimes } 2364b88c807SRodney W. Grimes 2374b88c807SRodney W. Grimes /* 2384b88c807SRodney W. Grimes * Routines common to the extended byte oriented cpio format 2394b88c807SRodney W. Grimes */ 2404b88c807SRodney W. Grimes 2414b88c807SRodney W. Grimes /* 2424b88c807SRodney W. Grimes * cpio_id() 2434b88c807SRodney W. Grimes * determine if a block given to us is a valid extended byte oriented 2444b88c807SRodney W. Grimes * cpio header 2454b88c807SRodney W. Grimes * Return: 2464b88c807SRodney W. Grimes * 0 if a valid header, -1 otherwise 2474b88c807SRodney W. Grimes */ 2484b88c807SRodney W. Grimes 2494b88c807SRodney W. Grimes int 2504b88c807SRodney W. Grimes cpio_id(char *blk, int size) 2514b88c807SRodney W. Grimes { 252cee22cbdSDavid E. O'Brien if ((size < (int)sizeof(HD_CPIO)) || 2534b88c807SRodney W. Grimes (strncmp(blk, AMAGIC, sizeof(AMAGIC) - 1) != 0)) 2544b88c807SRodney W. Grimes return(-1); 2554b88c807SRodney W. Grimes return(0); 2564b88c807SRodney W. Grimes } 2574b88c807SRodney W. Grimes 2584b88c807SRodney W. Grimes /* 2594b88c807SRodney W. Grimes * cpio_rd() 2604b88c807SRodney W. Grimes * determine if a buffer is a byte oriented extended cpio archive entry. 2614b88c807SRodney W. Grimes * convert and store the values in the ARCHD parameter. 2624b88c807SRodney W. Grimes * Return: 2634b88c807SRodney W. Grimes * 0 if a valid header, -1 otherwise. 2644b88c807SRodney W. Grimes */ 2654b88c807SRodney W. Grimes 2664b88c807SRodney W. Grimes int 267f789b261SWarner Losh cpio_rd(ARCHD *arcn, char *buf) 2684b88c807SRodney W. Grimes { 269f789b261SWarner Losh int nsz; 270f789b261SWarner Losh HD_CPIO *hd; 2714b88c807SRodney W. Grimes 2724b88c807SRodney W. Grimes /* 2734b88c807SRodney W. Grimes * check that this is a valid header, if not return -1 2744b88c807SRodney W. Grimes */ 2754b88c807SRodney W. Grimes if (cpio_id(buf, sizeof(HD_CPIO)) < 0) 2764b88c807SRodney W. Grimes return(-1); 277*f890020dSDag-Erling Smørgrav memset(arcn, 0, sizeof *arcn); 2784b88c807SRodney W. Grimes hd = (HD_CPIO *)buf; 2794b88c807SRodney W. Grimes 2804b88c807SRodney W. Grimes /* 2814b88c807SRodney W. Grimes * byte oriented cpio (posix) does not have padding! extract the octal 2824b88c807SRodney W. Grimes * ascii fields from the header 2834b88c807SRodney W. Grimes */ 2844b88c807SRodney W. Grimes arcn->sb.st_dev = (dev_t)asc_ul(hd->c_dev, sizeof(hd->c_dev), OCT); 2854b88c807SRodney W. Grimes arcn->sb.st_ino = (ino_t)asc_ul(hd->c_ino, sizeof(hd->c_ino), OCT); 2864b88c807SRodney W. Grimes arcn->sb.st_mode = (mode_t)asc_ul(hd->c_mode, sizeof(hd->c_mode), OCT); 2874b88c807SRodney W. Grimes arcn->sb.st_uid = (uid_t)asc_ul(hd->c_uid, sizeof(hd->c_uid), OCT); 2884b88c807SRodney W. Grimes arcn->sb.st_gid = (gid_t)asc_ul(hd->c_gid, sizeof(hd->c_gid), OCT); 2894b88c807SRodney W. Grimes arcn->sb.st_nlink = (nlink_t)asc_ul(hd->c_nlink, sizeof(hd->c_nlink), 2904b88c807SRodney W. Grimes OCT); 2914b88c807SRodney W. Grimes arcn->sb.st_rdev = (dev_t)asc_ul(hd->c_rdev, sizeof(hd->c_rdev), OCT); 2922ad45bbeSMatthew Dillon arcn->sb.st_mtime = (time_t)asc_uqd(hd->c_mtime, sizeof(hd->c_mtime), 2932ad45bbeSMatthew Dillon OCT); 2944b88c807SRodney W. Grimes arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime; 2954b88c807SRodney W. Grimes arcn->sb.st_size = (off_t)asc_uqd(hd->c_filesize,sizeof(hd->c_filesize), 2964b88c807SRodney W. Grimes OCT); 2974b88c807SRodney W. Grimes 2984b88c807SRodney W. Grimes /* 2994b88c807SRodney W. Grimes * check name size and if valid, read in the name of this entry (name 3004b88c807SRodney W. Grimes * follows header in the archive) 3014b88c807SRodney W. Grimes */ 3024b88c807SRodney W. Grimes if ((nsz = (int)asc_ul(hd->c_namesize,sizeof(hd->c_namesize),OCT)) < 2) 3034b88c807SRodney W. Grimes return(-1); 3044b88c807SRodney W. Grimes arcn->nlen = nsz - 1; 3054b88c807SRodney W. Grimes if (rd_nm(arcn, nsz) < 0) 3064b88c807SRodney W. Grimes return(-1); 3074b88c807SRodney W. Grimes 3084b88c807SRodney W. Grimes if (((arcn->sb.st_mode&C_IFMT) != C_ISLNK)||(arcn->sb.st_size == 0)) { 3094b88c807SRodney W. Grimes /* 3104b88c807SRodney W. Grimes * no link name to read for this file 3114b88c807SRodney W. Grimes */ 3124b88c807SRodney W. Grimes return(com_rd(arcn)); 3134b88c807SRodney W. Grimes } 3144b88c807SRodney W. Grimes 3154b88c807SRodney W. Grimes /* 3164b88c807SRodney W. Grimes * check link name size and read in the link name. Link names are 3174b88c807SRodney W. Grimes * stored like file data. 3184b88c807SRodney W. Grimes */ 3194b88c807SRodney W. Grimes if (rd_ln_nm(arcn) < 0) 3204b88c807SRodney W. Grimes return(-1); 3214b88c807SRodney W. Grimes 3224b88c807SRodney W. Grimes /* 3234b88c807SRodney W. Grimes * we have a valid header (with a link) 3244b88c807SRodney W. Grimes */ 3254b88c807SRodney W. Grimes return(com_rd(arcn)); 3264b88c807SRodney W. Grimes } 3274b88c807SRodney W. Grimes 3284b88c807SRodney W. Grimes /* 3294b88c807SRodney W. Grimes * cpio_endrd() 3304b88c807SRodney W. Grimes * no cleanup needed here, just return size of the trailer (for append) 3314b88c807SRodney W. Grimes * Return: 3324b88c807SRodney W. Grimes * size of trailer header in this format 3334b88c807SRodney W. Grimes */ 3344b88c807SRodney W. Grimes 3354b88c807SRodney W. Grimes off_t 3364b88c807SRodney W. Grimes cpio_endrd(void) 3374b88c807SRodney W. Grimes { 3384b88c807SRodney W. Grimes return((off_t)(sizeof(HD_CPIO) + sizeof(TRAILER))); 3394b88c807SRodney W. Grimes } 3404b88c807SRodney W. Grimes 3414b88c807SRodney W. Grimes /* 3424b88c807SRodney W. Grimes * cpio_stwr() 3434b88c807SRodney W. Grimes * start up the device mapping table 3444b88c807SRodney W. Grimes * Return: 3454b88c807SRodney W. Grimes * 0 if ok, -1 otherwise (what dev_start() returns) 3464b88c807SRodney W. Grimes */ 3474b88c807SRodney W. Grimes 3484b88c807SRodney W. Grimes int 3494b88c807SRodney W. Grimes cpio_stwr(void) 3504b88c807SRodney W. Grimes { 3514b88c807SRodney W. Grimes return(dev_start()); 3524b88c807SRodney W. Grimes } 3534b88c807SRodney W. Grimes 3544b88c807SRodney W. Grimes /* 3554b88c807SRodney W. Grimes * cpio_wr() 3564b88c807SRodney W. Grimes * copy the data in the ARCHD to buffer in extended byte oriented cpio 3574b88c807SRodney W. Grimes * format. 3584b88c807SRodney W. Grimes * Return 3594b88c807SRodney W. Grimes * 0 if file has data to be written after the header, 1 if file has NO 3604b88c807SRodney W. Grimes * data to write after the header, -1 if archive write failed 3614b88c807SRodney W. Grimes */ 3624b88c807SRodney W. Grimes 3634b88c807SRodney W. Grimes int 364f789b261SWarner Losh cpio_wr(ARCHD *arcn) 3654b88c807SRodney W. Grimes { 366f789b261SWarner Losh HD_CPIO *hd; 367f789b261SWarner Losh int nsz; 368c65bb135SRuslan Ermilov HD_CPIO hdblk; 3694b88c807SRodney W. Grimes 3704b88c807SRodney W. Grimes /* 3714b88c807SRodney W. Grimes * check and repair truncated device and inode fields in the header 3724b88c807SRodney W. Grimes */ 3734b88c807SRodney W. Grimes if (map_dev(arcn, (u_long)CPIO_MASK, (u_long)CPIO_MASK) < 0) 3744b88c807SRodney W. Grimes return(-1); 3754b88c807SRodney W. Grimes 3764b88c807SRodney W. Grimes arcn->pad = 0L; 3774b88c807SRodney W. Grimes nsz = arcn->nlen + 1; 378c65bb135SRuslan Ermilov hd = &hdblk; 3794b88c807SRodney W. Grimes if ((arcn->type != PAX_BLK) && (arcn->type != PAX_CHR)) 3804b88c807SRodney W. Grimes arcn->sb.st_rdev = 0; 3814b88c807SRodney W. Grimes 3824b88c807SRodney W. Grimes switch(arcn->type) { 3834b88c807SRodney W. Grimes case PAX_CTG: 3844b88c807SRodney W. Grimes case PAX_REG: 3854b88c807SRodney W. Grimes case PAX_HRG: 3864b88c807SRodney W. Grimes /* 3874b88c807SRodney W. Grimes * set data size for file data 3884b88c807SRodney W. Grimes */ 3894b88c807SRodney W. Grimes if (uqd_asc((u_quad_t)arcn->sb.st_size, hd->c_filesize, 3904b88c807SRodney W. Grimes sizeof(hd->c_filesize), OCT)) { 391778766feSKris Kennaway paxwarn(1,"File is too large for cpio format %s", 3924b88c807SRodney W. Grimes arcn->org_name); 3934b88c807SRodney W. Grimes return(1); 3944b88c807SRodney W. Grimes } 3954b88c807SRodney W. Grimes break; 3964b88c807SRodney W. Grimes case PAX_SLK: 3974b88c807SRodney W. Grimes /* 3984b88c807SRodney W. Grimes * set data size to hold link name 3994b88c807SRodney W. Grimes */ 4004b88c807SRodney W. Grimes if (ul_asc((u_long)arcn->ln_nlen, hd->c_filesize, 4014b88c807SRodney W. Grimes sizeof(hd->c_filesize), OCT)) 4024b88c807SRodney W. Grimes goto out; 4034b88c807SRodney W. Grimes break; 4044b88c807SRodney W. Grimes default: 4054b88c807SRodney W. Grimes /* 4064b88c807SRodney W. Grimes * all other file types have no file data 4074b88c807SRodney W. Grimes */ 4084b88c807SRodney W. Grimes if (ul_asc((u_long)0, hd->c_filesize, sizeof(hd->c_filesize), 4094b88c807SRodney W. Grimes OCT)) 4104b88c807SRodney W. Grimes goto out; 4114b88c807SRodney W. Grimes break; 4124b88c807SRodney W. Grimes } 4134b88c807SRodney W. Grimes 4144b88c807SRodney W. Grimes /* 4154b88c807SRodney W. Grimes * copy the values to the header using octal ascii 4164b88c807SRodney W. Grimes */ 4174b88c807SRodney W. Grimes if (ul_asc((u_long)MAGIC, hd->c_magic, sizeof(hd->c_magic), OCT) || 4184b88c807SRodney W. Grimes ul_asc((u_long)arcn->sb.st_dev, hd->c_dev, sizeof(hd->c_dev), 4194b88c807SRodney W. Grimes OCT) || 4204b88c807SRodney W. Grimes ul_asc((u_long)arcn->sb.st_ino, hd->c_ino, sizeof(hd->c_ino), 4214b88c807SRodney W. Grimes OCT) || 4224b88c807SRodney W. Grimes ul_asc((u_long)arcn->sb.st_mode, hd->c_mode, sizeof(hd->c_mode), 4234b88c807SRodney W. Grimes OCT) || 4244b88c807SRodney W. Grimes ul_asc((u_long)arcn->sb.st_uid, hd->c_uid, sizeof(hd->c_uid), 4254b88c807SRodney W. Grimes OCT) || 4264b88c807SRodney W. Grimes ul_asc((u_long)arcn->sb.st_gid, hd->c_gid, sizeof(hd->c_gid), 4274b88c807SRodney W. Grimes OCT) || 4284b88c807SRodney W. Grimes ul_asc((u_long)arcn->sb.st_nlink, hd->c_nlink, sizeof(hd->c_nlink), 4294b88c807SRodney W. Grimes OCT) || 4304b88c807SRodney W. Grimes ul_asc((u_long)arcn->sb.st_rdev, hd->c_rdev, sizeof(hd->c_rdev), 4314b88c807SRodney W. Grimes OCT) || 4324b88c807SRodney W. Grimes ul_asc((u_long)arcn->sb.st_mtime,hd->c_mtime,sizeof(hd->c_mtime), 4334b88c807SRodney W. Grimes OCT) || 4344b88c807SRodney W. Grimes ul_asc((u_long)nsz, hd->c_namesize, sizeof(hd->c_namesize), OCT)) 4354b88c807SRodney W. Grimes goto out; 4364b88c807SRodney W. Grimes 4374b88c807SRodney W. Grimes /* 4384b88c807SRodney W. Grimes * write the file name to the archive 4394b88c807SRodney W. Grimes */ 440c65bb135SRuslan Ermilov if ((wr_rdbuf((char *)&hdblk, (int)sizeof(HD_CPIO)) < 0) || 4414b88c807SRodney W. Grimes (wr_rdbuf(arcn->name, nsz) < 0)) { 442778766feSKris Kennaway paxwarn(1, "Unable to write cpio header for %s", arcn->org_name); 4434b88c807SRodney W. Grimes return(-1); 4444b88c807SRodney W. Grimes } 4454b88c807SRodney W. Grimes 4464b88c807SRodney W. Grimes /* 4474b88c807SRodney W. Grimes * if this file has data, we are done. The caller will write the file 4484b88c807SRodney W. Grimes * data, if we are link tell caller we are done, go to next file 4494b88c807SRodney W. Grimes */ 4504b88c807SRodney W. Grimes if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG) || 4514b88c807SRodney W. Grimes (arcn->type == PAX_HRG)) 4524b88c807SRodney W. Grimes return(0); 4534b88c807SRodney W. Grimes if (arcn->type != PAX_SLK) 4544b88c807SRodney W. Grimes return(1); 4554b88c807SRodney W. Grimes 4564b88c807SRodney W. Grimes /* 4574b88c807SRodney W. Grimes * write the link name to the archive, tell the caller to go to the 4584b88c807SRodney W. Grimes * next file as we are done. 4594b88c807SRodney W. Grimes */ 4604b88c807SRodney W. Grimes if (wr_rdbuf(arcn->ln_name, arcn->ln_nlen) < 0) { 461778766feSKris Kennaway paxwarn(1,"Unable to write cpio link name for %s",arcn->org_name); 4624b88c807SRodney W. Grimes return(-1); 4634b88c807SRodney W. Grimes } 4644b88c807SRodney W. Grimes return(1); 4654b88c807SRodney W. Grimes 4664b88c807SRodney W. Grimes out: 4674b88c807SRodney W. Grimes /* 4684b88c807SRodney W. Grimes * header field is out of range 4694b88c807SRodney W. Grimes */ 470778766feSKris Kennaway paxwarn(1, "Cpio header field is too small to store file %s", 4714b88c807SRodney W. Grimes arcn->org_name); 4724b88c807SRodney W. Grimes return(1); 4734b88c807SRodney W. Grimes } 4744b88c807SRodney W. Grimes 4754b88c807SRodney W. Grimes /* 4764b88c807SRodney W. Grimes * Routines common to the system VR4 version of cpio (with/without file CRC) 4774b88c807SRodney W. Grimes */ 4784b88c807SRodney W. Grimes 4794b88c807SRodney W. Grimes /* 4804b88c807SRodney W. Grimes * vcpio_id() 4814b88c807SRodney W. Grimes * determine if a block given to us is a valid system VR4 cpio header 4824b88c807SRodney W. Grimes * WITHOUT crc. WATCH it the magic cookies are in OCTAL, the header 4834b88c807SRodney W. Grimes * uses HEX 4844b88c807SRodney W. Grimes * Return: 4854b88c807SRodney W. Grimes * 0 if a valid header, -1 otherwise 4864b88c807SRodney W. Grimes */ 4874b88c807SRodney W. Grimes 4884b88c807SRodney W. Grimes int 4894b88c807SRodney W. Grimes vcpio_id(char *blk, int size) 4904b88c807SRodney W. Grimes { 491cee22cbdSDavid E. O'Brien if ((size < (int)sizeof(HD_VCPIO)) || 4924b88c807SRodney W. Grimes (strncmp(blk, AVMAGIC, sizeof(AVMAGIC) - 1) != 0)) 4934b88c807SRodney W. Grimes return(-1); 4944b88c807SRodney W. Grimes return(0); 4954b88c807SRodney W. Grimes } 4964b88c807SRodney W. Grimes 4974b88c807SRodney W. Grimes /* 4984b88c807SRodney W. Grimes * crc_id() 4994b88c807SRodney W. Grimes * determine if a block given to us is a valid system VR4 cpio header 5004b88c807SRodney W. Grimes * WITH crc. WATCH it the magic cookies are in OCTAL the header uses HEX 5014b88c807SRodney W. Grimes * Return: 5024b88c807SRodney W. Grimes * 0 if a valid header, -1 otherwise 5034b88c807SRodney W. Grimes */ 5044b88c807SRodney W. Grimes 5054b88c807SRodney W. Grimes int 5064b88c807SRodney W. Grimes crc_id(char *blk, int size) 5074b88c807SRodney W. Grimes { 508cee22cbdSDavid E. O'Brien if ((size < (int)sizeof(HD_VCPIO)) || 509cee22cbdSDavid E. O'Brien (strncmp(blk, AVCMAGIC, (int)sizeof(AVCMAGIC) - 1) != 0)) 5104b88c807SRodney W. Grimes return(-1); 5114b88c807SRodney W. Grimes return(0); 5124b88c807SRodney W. Grimes } 5134b88c807SRodney W. Grimes 5144b88c807SRodney W. Grimes /* 5154b88c807SRodney W. Grimes * crc_strd() 5164b88c807SRodney W. Grimes w set file data CRC calculations. Fire up the hard link detection code 5174b88c807SRodney W. Grimes * Return: 5184b88c807SRodney W. Grimes * 0 if ok -1 otherwise (the return values of lnk_start()) 5194b88c807SRodney W. Grimes */ 5204b88c807SRodney W. Grimes 5214b88c807SRodney W. Grimes int 5224b88c807SRodney W. Grimes crc_strd(void) 5234b88c807SRodney W. Grimes { 5244b88c807SRodney W. Grimes docrc = 1; 5254b88c807SRodney W. Grimes return(lnk_start()); 5264b88c807SRodney W. Grimes } 5274b88c807SRodney W. Grimes 5284b88c807SRodney W. Grimes /* 5294b88c807SRodney W. Grimes * vcpio_rd() 5304b88c807SRodney W. Grimes * determine if a buffer is a system VR4 archive entry. (with/without CRC) 5314b88c807SRodney W. Grimes * convert and store the values in the ARCHD parameter. 5324b88c807SRodney W. Grimes * Return: 5334b88c807SRodney W. Grimes * 0 if a valid header, -1 otherwise. 5344b88c807SRodney W. Grimes */ 5354b88c807SRodney W. Grimes 5364b88c807SRodney W. Grimes int 537f789b261SWarner Losh vcpio_rd(ARCHD *arcn, char *buf) 5384b88c807SRodney W. Grimes { 539f789b261SWarner Losh HD_VCPIO *hd; 5404b88c807SRodney W. Grimes dev_t devminor; 5414b88c807SRodney W. Grimes dev_t devmajor; 542f789b261SWarner Losh int nsz; 5434b88c807SRodney W. Grimes 5444b88c807SRodney W. Grimes /* 5454b88c807SRodney W. Grimes * during the id phase it was determined if we were using CRC, use the 5464b88c807SRodney W. Grimes * proper id routine. 5474b88c807SRodney W. Grimes */ 5484b88c807SRodney W. Grimes if (docrc) { 5494b88c807SRodney W. Grimes if (crc_id(buf, sizeof(HD_VCPIO)) < 0) 5504b88c807SRodney W. Grimes return(-1); 5514b88c807SRodney W. Grimes } else { 5524b88c807SRodney W. Grimes if (vcpio_id(buf, sizeof(HD_VCPIO)) < 0) 5534b88c807SRodney W. Grimes return(-1); 5544b88c807SRodney W. Grimes } 5554b88c807SRodney W. Grimes 556*f890020dSDag-Erling Smørgrav memset(arcn, 0, sizeof *arcn); 5574b88c807SRodney W. Grimes hd = (HD_VCPIO *)buf; 5584b88c807SRodney W. Grimes 5594b88c807SRodney W. Grimes /* 5604b88c807SRodney W. Grimes * extract the hex ascii fields from the header 5614b88c807SRodney W. Grimes */ 5624b88c807SRodney W. Grimes arcn->sb.st_ino = (ino_t)asc_ul(hd->c_ino, sizeof(hd->c_ino), HEX); 5634b88c807SRodney W. Grimes arcn->sb.st_mode = (mode_t)asc_ul(hd->c_mode, sizeof(hd->c_mode), HEX); 5644b88c807SRodney W. Grimes arcn->sb.st_uid = (uid_t)asc_ul(hd->c_uid, sizeof(hd->c_uid), HEX); 5654b88c807SRodney W. Grimes arcn->sb.st_gid = (gid_t)asc_ul(hd->c_gid, sizeof(hd->c_gid), HEX); 5662ad45bbeSMatthew Dillon arcn->sb.st_mtime = (time_t)asc_uqd(hd->c_mtime,sizeof(hd->c_mtime),HEX); 5674b88c807SRodney W. Grimes arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime; 5684b88c807SRodney W. Grimes arcn->sb.st_size = (off_t)asc_uqd(hd->c_filesize, 5694b88c807SRodney W. Grimes sizeof(hd->c_filesize), HEX); 5704b88c807SRodney W. Grimes arcn->sb.st_nlink = (nlink_t)asc_ul(hd->c_nlink, sizeof(hd->c_nlink), 5714b88c807SRodney W. Grimes HEX); 5724b88c807SRodney W. Grimes devmajor = (dev_t)asc_ul(hd->c_maj, sizeof(hd->c_maj), HEX); 5734b88c807SRodney W. Grimes devminor = (dev_t)asc_ul(hd->c_min, sizeof(hd->c_min), HEX); 5744b88c807SRodney W. Grimes arcn->sb.st_dev = TODEV(devmajor, devminor); 5754b88c807SRodney W. Grimes devmajor = (dev_t)asc_ul(hd->c_rmaj, sizeof(hd->c_maj), HEX); 5764b88c807SRodney W. Grimes devminor = (dev_t)asc_ul(hd->c_rmin, sizeof(hd->c_min), HEX); 5774b88c807SRodney W. Grimes arcn->sb.st_rdev = TODEV(devmajor, devminor); 5784b88c807SRodney W. Grimes arcn->crc = asc_ul(hd->c_chksum, sizeof(hd->c_chksum), HEX); 5794b88c807SRodney W. Grimes 5804b88c807SRodney W. Grimes /* 5814b88c807SRodney W. Grimes * check the length of the file name, if ok read it in, return -1 if 5824b88c807SRodney W. Grimes * bogus 5834b88c807SRodney W. Grimes */ 5844b88c807SRodney W. Grimes if ((nsz = (int)asc_ul(hd->c_namesize,sizeof(hd->c_namesize),HEX)) < 2) 5854b88c807SRodney W. Grimes return(-1); 5864b88c807SRodney W. Grimes arcn->nlen = nsz - 1; 5874b88c807SRodney W. Grimes if (rd_nm(arcn, nsz) < 0) 5884b88c807SRodney W. Grimes return(-1); 5894b88c807SRodney W. Grimes 5904b88c807SRodney W. Grimes /* 59101c99176SUlrich Spörlein * skip padding. header + filename is aligned to 4 byte boundaries 5924b88c807SRodney W. Grimes */ 5934b88c807SRodney W. Grimes if (rd_skip((off_t)(VCPIO_PAD(sizeof(HD_VCPIO) + nsz))) < 0) 5944b88c807SRodney W. Grimes return(-1); 5954b88c807SRodney W. Grimes 5964b88c807SRodney W. Grimes /* 5974b88c807SRodney W. Grimes * if not a link (or a file with no data), calculate pad size (for 5984b88c807SRodney W. Grimes * padding which follows the file data), clear the link name and return 5994b88c807SRodney W. Grimes */ 6004b88c807SRodney W. Grimes if (((arcn->sb.st_mode&C_IFMT) != C_ISLNK)||(arcn->sb.st_size == 0)) { 6014b88c807SRodney W. Grimes /* 6024b88c807SRodney W. Grimes * we have a valid header (not a link) 6034b88c807SRodney W. Grimes */ 6044b88c807SRodney W. Grimes arcn->pad = VCPIO_PAD(arcn->sb.st_size); 6054b88c807SRodney W. Grimes return(com_rd(arcn)); 6064b88c807SRodney W. Grimes } 6074b88c807SRodney W. Grimes 6084b88c807SRodney W. Grimes /* 6094b88c807SRodney W. Grimes * read in the link name and skip over the padding 6104b88c807SRodney W. Grimes */ 6114b88c807SRodney W. Grimes if ((rd_ln_nm(arcn) < 0) || 6124b88c807SRodney W. Grimes (rd_skip((off_t)(VCPIO_PAD(arcn->sb.st_size))) < 0)) 6134b88c807SRodney W. Grimes return(-1); 6144b88c807SRodney W. Grimes 6154b88c807SRodney W. Grimes /* 6164b88c807SRodney W. Grimes * we have a valid header (with a link) 6174b88c807SRodney W. Grimes */ 6184b88c807SRodney W. Grimes return(com_rd(arcn)); 6194b88c807SRodney W. Grimes } 6204b88c807SRodney W. Grimes 6214b88c807SRodney W. Grimes /* 6224b88c807SRodney W. Grimes * vcpio_endrd() 6234b88c807SRodney W. Grimes * no cleanup needed here, just return size of the trailer (for append) 6244b88c807SRodney W. Grimes * Return: 6254b88c807SRodney W. Grimes * size of trailer header in this format 6264b88c807SRodney W. Grimes */ 6274b88c807SRodney W. Grimes 6284b88c807SRodney W. Grimes off_t 6294b88c807SRodney W. Grimes vcpio_endrd(void) 6304b88c807SRodney W. Grimes { 6314b88c807SRodney W. Grimes return((off_t)(sizeof(HD_VCPIO) + sizeof(TRAILER) + 6324b88c807SRodney W. Grimes (VCPIO_PAD(sizeof(HD_VCPIO) + sizeof(TRAILER))))); 6334b88c807SRodney W. Grimes } 6344b88c807SRodney W. Grimes 6354b88c807SRodney W. Grimes /* 6364b88c807SRodney W. Grimes * crc_stwr() 6374b88c807SRodney W. Grimes * start up the device mapping table, enable crc file calculation 6384b88c807SRodney W. Grimes * Return: 6394b88c807SRodney W. Grimes * 0 if ok, -1 otherwise (what dev_start() returns) 6404b88c807SRodney W. Grimes */ 6414b88c807SRodney W. Grimes 6424b88c807SRodney W. Grimes int 6434b88c807SRodney W. Grimes crc_stwr(void) 6444b88c807SRodney W. Grimes { 6454b88c807SRodney W. Grimes docrc = 1; 6464b88c807SRodney W. Grimes return(dev_start()); 6474b88c807SRodney W. Grimes } 6484b88c807SRodney W. Grimes 6494b88c807SRodney W. Grimes /* 6504b88c807SRodney W. Grimes * vcpio_wr() 6514b88c807SRodney W. Grimes * copy the data in the ARCHD to buffer in system VR4 cpio 6524b88c807SRodney W. Grimes * (with/without crc) format. 6534b88c807SRodney W. Grimes * Return 6544b88c807SRodney W. Grimes * 0 if file has data to be written after the header, 1 if file has 6554b88c807SRodney W. Grimes * NO data to write after the header, -1 if archive write failed 6564b88c807SRodney W. Grimes */ 6574b88c807SRodney W. Grimes 6584b88c807SRodney W. Grimes int 659f789b261SWarner Losh vcpio_wr(ARCHD *arcn) 6604b88c807SRodney W. Grimes { 661f789b261SWarner Losh HD_VCPIO *hd; 6624b88c807SRodney W. Grimes unsigned int nsz; 663c65bb135SRuslan Ermilov HD_VCPIO hdblk; 6644b88c807SRodney W. Grimes 6654b88c807SRodney W. Grimes /* 6664b88c807SRodney W. Grimes * check and repair truncated device and inode fields in the cpio 6674b88c807SRodney W. Grimes * header 6684b88c807SRodney W. Grimes */ 6694b88c807SRodney W. Grimes if (map_dev(arcn, (u_long)VCPIO_MASK, (u_long)VCPIO_MASK) < 0) 6704b88c807SRodney W. Grimes return(-1); 6714b88c807SRodney W. Grimes nsz = arcn->nlen + 1; 672c65bb135SRuslan Ermilov hd = &hdblk; 6734b88c807SRodney W. Grimes if ((arcn->type != PAX_BLK) && (arcn->type != PAX_CHR)) 6744b88c807SRodney W. Grimes arcn->sb.st_rdev = 0; 6754b88c807SRodney W. Grimes 6764b88c807SRodney W. Grimes /* 6774b88c807SRodney W. Grimes * add the proper magic value depending whether we were asked for 6784b88c807SRodney W. Grimes * file data crc's, and the crc if needed. 6794b88c807SRodney W. Grimes */ 6804b88c807SRodney W. Grimes if (docrc) { 6814b88c807SRodney W. Grimes if (ul_asc((u_long)VCMAGIC, hd->c_magic, sizeof(hd->c_magic), 6824b88c807SRodney W. Grimes OCT) || 6834b88c807SRodney W. Grimes ul_asc((u_long)arcn->crc,hd->c_chksum,sizeof(hd->c_chksum), 6844b88c807SRodney W. Grimes HEX)) 6854b88c807SRodney W. Grimes goto out; 6864b88c807SRodney W. Grimes } else { 6874b88c807SRodney W. Grimes if (ul_asc((u_long)VMAGIC, hd->c_magic, sizeof(hd->c_magic), 6884b88c807SRodney W. Grimes OCT) || 6894b88c807SRodney W. Grimes ul_asc((u_long)0L, hd->c_chksum, sizeof(hd->c_chksum),HEX)) 6904b88c807SRodney W. Grimes goto out; 6914b88c807SRodney W. Grimes } 6924b88c807SRodney W. Grimes 6934b88c807SRodney W. Grimes switch(arcn->type) { 6944b88c807SRodney W. Grimes case PAX_CTG: 6954b88c807SRodney W. Grimes case PAX_REG: 6964b88c807SRodney W. Grimes case PAX_HRG: 6974b88c807SRodney W. Grimes /* 6984b88c807SRodney W. Grimes * caller will copy file data to the archive. tell him how 6994b88c807SRodney W. Grimes * much to pad. 7004b88c807SRodney W. Grimes */ 7014b88c807SRodney W. Grimes arcn->pad = VCPIO_PAD(arcn->sb.st_size); 7024b88c807SRodney W. Grimes if (uqd_asc((u_quad_t)arcn->sb.st_size, hd->c_filesize, 7034b88c807SRodney W. Grimes sizeof(hd->c_filesize), HEX)) { 704778766feSKris Kennaway paxwarn(1,"File is too large for sv4cpio format %s", 7054b88c807SRodney W. Grimes arcn->org_name); 7064b88c807SRodney W. Grimes return(1); 7074b88c807SRodney W. Grimes } 7084b88c807SRodney W. Grimes break; 7094b88c807SRodney W. Grimes case PAX_SLK: 7104b88c807SRodney W. Grimes /* 7114b88c807SRodney W. Grimes * no file data for the caller to process, the file data has 7124b88c807SRodney W. Grimes * the size of the link 7134b88c807SRodney W. Grimes */ 7144b88c807SRodney W. Grimes arcn->pad = 0L; 7154b88c807SRodney W. Grimes if (ul_asc((u_long)arcn->ln_nlen, hd->c_filesize, 7164b88c807SRodney W. Grimes sizeof(hd->c_filesize), HEX)) 7174b88c807SRodney W. Grimes goto out; 7184b88c807SRodney W. Grimes break; 7194b88c807SRodney W. Grimes default: 7204b88c807SRodney W. Grimes /* 7214b88c807SRodney W. Grimes * no file data for the caller to process 7224b88c807SRodney W. Grimes */ 7234b88c807SRodney W. Grimes arcn->pad = 0L; 7244b88c807SRodney W. Grimes if (ul_asc((u_long)0L, hd->c_filesize, sizeof(hd->c_filesize), 7254b88c807SRodney W. Grimes HEX)) 7264b88c807SRodney W. Grimes goto out; 7274b88c807SRodney W. Grimes break; 7284b88c807SRodney W. Grimes } 7294b88c807SRodney W. Grimes 7304b88c807SRodney W. Grimes /* 7314b88c807SRodney W. Grimes * set the other fields in the header 7324b88c807SRodney W. Grimes */ 7334b88c807SRodney W. Grimes if (ul_asc((u_long)arcn->sb.st_ino, hd->c_ino, sizeof(hd->c_ino), 7344b88c807SRodney W. Grimes HEX) || 7354b88c807SRodney W. Grimes ul_asc((u_long)arcn->sb.st_mode, hd->c_mode, sizeof(hd->c_mode), 7364b88c807SRodney W. Grimes HEX) || 7374b88c807SRodney W. Grimes ul_asc((u_long)arcn->sb.st_uid, hd->c_uid, sizeof(hd->c_uid), 7384b88c807SRodney W. Grimes HEX) || 7394b88c807SRodney W. Grimes ul_asc((u_long)arcn->sb.st_gid, hd->c_gid, sizeof(hd->c_gid), 7404b88c807SRodney W. Grimes HEX) || 7414b88c807SRodney W. Grimes ul_asc((u_long)arcn->sb.st_mtime, hd->c_mtime, sizeof(hd->c_mtime), 7424b88c807SRodney W. Grimes HEX) || 7434b88c807SRodney W. Grimes ul_asc((u_long)arcn->sb.st_nlink, hd->c_nlink, sizeof(hd->c_nlink), 7444b88c807SRodney W. Grimes HEX) || 7454b88c807SRodney W. Grimes ul_asc((u_long)MAJOR(arcn->sb.st_dev),hd->c_maj, sizeof(hd->c_maj), 7464b88c807SRodney W. Grimes HEX) || 7474b88c807SRodney W. Grimes ul_asc((u_long)MINOR(arcn->sb.st_dev),hd->c_min, sizeof(hd->c_min), 7484b88c807SRodney W. Grimes HEX) || 7494b88c807SRodney W. Grimes ul_asc((u_long)MAJOR(arcn->sb.st_rdev),hd->c_rmaj,sizeof(hd->c_maj), 7504b88c807SRodney W. Grimes HEX) || 7514b88c807SRodney W. Grimes ul_asc((u_long)MINOR(arcn->sb.st_rdev),hd->c_rmin,sizeof(hd->c_min), 7524b88c807SRodney W. Grimes HEX) || 7534b88c807SRodney W. Grimes ul_asc((u_long)nsz, hd->c_namesize, sizeof(hd->c_namesize), HEX)) 7544b88c807SRodney W. Grimes goto out; 7554b88c807SRodney W. Grimes 7564b88c807SRodney W. Grimes /* 7574b88c807SRodney W. Grimes * write the header, the file name and padding as required. 7584b88c807SRodney W. Grimes */ 759c65bb135SRuslan Ermilov if ((wr_rdbuf((char *)&hdblk, (int)sizeof(HD_VCPIO)) < 0) || 7604b88c807SRodney W. Grimes (wr_rdbuf(arcn->name, (int)nsz) < 0) || 7614b88c807SRodney W. Grimes (wr_skip((off_t)(VCPIO_PAD(sizeof(HD_VCPIO) + nsz))) < 0)) { 762778766feSKris Kennaway paxwarn(1,"Could not write sv4cpio header for %s",arcn->org_name); 7634b88c807SRodney W. Grimes return(-1); 7644b88c807SRodney W. Grimes } 7654b88c807SRodney W. Grimes 7664b88c807SRodney W. Grimes /* 7674b88c807SRodney W. Grimes * if we have file data, tell the caller we are done, copy the file 7684b88c807SRodney W. Grimes */ 7694b88c807SRodney W. Grimes if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG) || 7704b88c807SRodney W. Grimes (arcn->type == PAX_HRG)) 7714b88c807SRodney W. Grimes return(0); 7724b88c807SRodney W. Grimes 7734b88c807SRodney W. Grimes /* 7744b88c807SRodney W. Grimes * if we are not a link, tell the caller we are done, go to next file 7754b88c807SRodney W. Grimes */ 7764b88c807SRodney W. Grimes if (arcn->type != PAX_SLK) 7774b88c807SRodney W. Grimes return(1); 7784b88c807SRodney W. Grimes 7794b88c807SRodney W. Grimes /* 7804b88c807SRodney W. Grimes * write the link name, tell the caller we are done. 7814b88c807SRodney W. Grimes */ 7824b88c807SRodney W. Grimes if ((wr_rdbuf(arcn->ln_name, arcn->ln_nlen) < 0) || 7834b88c807SRodney W. Grimes (wr_skip((off_t)(VCPIO_PAD(arcn->ln_nlen))) < 0)) { 784778766feSKris Kennaway paxwarn(1,"Could not write sv4cpio link name for %s", 7854b88c807SRodney W. Grimes arcn->org_name); 7864b88c807SRodney W. Grimes return(-1); 7874b88c807SRodney W. Grimes } 7884b88c807SRodney W. Grimes return(1); 7894b88c807SRodney W. Grimes 7904b88c807SRodney W. Grimes out: 7914b88c807SRodney W. Grimes /* 7924b88c807SRodney W. Grimes * header field is out of range 7934b88c807SRodney W. Grimes */ 794778766feSKris Kennaway paxwarn(1,"Sv4cpio header field is too small for file %s",arcn->org_name); 7954b88c807SRodney W. Grimes return(1); 7964b88c807SRodney W. Grimes } 7974b88c807SRodney W. Grimes 7984b88c807SRodney W. Grimes /* 7994b88c807SRodney W. Grimes * Routines common to the old binary header cpio 8004b88c807SRodney W. Grimes */ 8014b88c807SRodney W. Grimes 8024b88c807SRodney W. Grimes /* 8034b88c807SRodney W. Grimes * bcpio_id() 8049d5abbddSJens Schweikhardt * determine if a block given to us is an old binary cpio header 8054b88c807SRodney W. Grimes * (with/without header byte swapping) 8064b88c807SRodney W. Grimes * Return: 8074b88c807SRodney W. Grimes * 0 if a valid header, -1 otherwise 8084b88c807SRodney W. Grimes */ 8094b88c807SRodney W. Grimes 8104b88c807SRodney W. Grimes int 8114b88c807SRodney W. Grimes bcpio_id(char *blk, int size) 8124b88c807SRodney W. Grimes { 813cee22cbdSDavid E. O'Brien if (size < (int)sizeof(HD_BCPIO)) 8144b88c807SRodney W. Grimes return(-1); 8154b88c807SRodney W. Grimes 8164b88c807SRodney W. Grimes /* 8174b88c807SRodney W. Grimes * check both normal and byte swapped magic cookies 8184b88c807SRodney W. Grimes */ 8194b88c807SRodney W. Grimes if (((u_short)SHRT_EXT(blk)) == MAGIC) 8204b88c807SRodney W. Grimes return(0); 8214b88c807SRodney W. Grimes if (((u_short)RSHRT_EXT(blk)) == MAGIC) { 8224b88c807SRodney W. Grimes if (!swp_head) 8234b88c807SRodney W. Grimes ++swp_head; 8244b88c807SRodney W. Grimes return(0); 8254b88c807SRodney W. Grimes } 8264b88c807SRodney W. Grimes return(-1); 8274b88c807SRodney W. Grimes } 8284b88c807SRodney W. Grimes 8294b88c807SRodney W. Grimes /* 8304b88c807SRodney W. Grimes * bcpio_rd() 8319d5abbddSJens Schweikhardt * determine if a buffer is an old binary archive entry. (It may have byte 8324b88c807SRodney W. Grimes * swapped header) convert and store the values in the ARCHD parameter. 8334b88c807SRodney W. Grimes * This is a very old header format and should not really be used. 8344b88c807SRodney W. Grimes * Return: 8354b88c807SRodney W. Grimes * 0 if a valid header, -1 otherwise. 8364b88c807SRodney W. Grimes */ 8374b88c807SRodney W. Grimes 8384b88c807SRodney W. Grimes int 839f789b261SWarner Losh bcpio_rd(ARCHD *arcn, char *buf) 8404b88c807SRodney W. Grimes { 841f789b261SWarner Losh HD_BCPIO *hd; 842f789b261SWarner Losh int nsz; 8434b88c807SRodney W. Grimes 8444b88c807SRodney W. Grimes /* 8454b88c807SRodney W. Grimes * check the header 8464b88c807SRodney W. Grimes */ 8474b88c807SRodney W. Grimes if (bcpio_id(buf, sizeof(HD_BCPIO)) < 0) 8484b88c807SRodney W. Grimes return(-1); 8494b88c807SRodney W. Grimes 850*f890020dSDag-Erling Smørgrav memset(arcn, 0, sizeof *arcn); 8514b88c807SRodney W. Grimes hd = (HD_BCPIO *)buf; 8524b88c807SRodney W. Grimes if (swp_head) { 8534b88c807SRodney W. Grimes /* 85446be34b9SKris Kennaway * header has swapped bytes on 16 bit boundaries 8554b88c807SRodney W. Grimes */ 8564b88c807SRodney W. Grimes arcn->sb.st_dev = (dev_t)(RSHRT_EXT(hd->h_dev)); 8574b88c807SRodney W. Grimes arcn->sb.st_ino = (ino_t)(RSHRT_EXT(hd->h_ino)); 8584b88c807SRodney W. Grimes arcn->sb.st_mode = (mode_t)(RSHRT_EXT(hd->h_mode)); 8594b88c807SRodney W. Grimes arcn->sb.st_uid = (uid_t)(RSHRT_EXT(hd->h_uid)); 8604b88c807SRodney W. Grimes arcn->sb.st_gid = (gid_t)(RSHRT_EXT(hd->h_gid)); 8614b88c807SRodney W. Grimes arcn->sb.st_nlink = (nlink_t)(RSHRT_EXT(hd->h_nlink)); 8624b88c807SRodney W. Grimes arcn->sb.st_rdev = (dev_t)(RSHRT_EXT(hd->h_rdev)); 8634b88c807SRodney W. Grimes arcn->sb.st_mtime = (time_t)(RSHRT_EXT(hd->h_mtime_1)); 8644b88c807SRodney W. Grimes arcn->sb.st_mtime = (arcn->sb.st_mtime << 16) | 8654b88c807SRodney W. Grimes ((time_t)(RSHRT_EXT(hd->h_mtime_2))); 8664b88c807SRodney W. Grimes arcn->sb.st_size = (off_t)(RSHRT_EXT(hd->h_filesize_1)); 8674b88c807SRodney W. Grimes arcn->sb.st_size = (arcn->sb.st_size << 16) | 8684b88c807SRodney W. Grimes ((off_t)(RSHRT_EXT(hd->h_filesize_2))); 8694b88c807SRodney W. Grimes nsz = (int)(RSHRT_EXT(hd->h_namesize)); 8704b88c807SRodney W. Grimes } else { 8714b88c807SRodney W. Grimes arcn->sb.st_dev = (dev_t)(SHRT_EXT(hd->h_dev)); 8724b88c807SRodney W. Grimes arcn->sb.st_ino = (ino_t)(SHRT_EXT(hd->h_ino)); 8734b88c807SRodney W. Grimes arcn->sb.st_mode = (mode_t)(SHRT_EXT(hd->h_mode)); 8744b88c807SRodney W. Grimes arcn->sb.st_uid = (uid_t)(SHRT_EXT(hd->h_uid)); 8754b88c807SRodney W. Grimes arcn->sb.st_gid = (gid_t)(SHRT_EXT(hd->h_gid)); 8764b88c807SRodney W. Grimes arcn->sb.st_nlink = (nlink_t)(SHRT_EXT(hd->h_nlink)); 8774b88c807SRodney W. Grimes arcn->sb.st_rdev = (dev_t)(SHRT_EXT(hd->h_rdev)); 8784b88c807SRodney W. Grimes arcn->sb.st_mtime = (time_t)(SHRT_EXT(hd->h_mtime_1)); 8794b88c807SRodney W. Grimes arcn->sb.st_mtime = (arcn->sb.st_mtime << 16) | 8804b88c807SRodney W. Grimes ((time_t)(SHRT_EXT(hd->h_mtime_2))); 8814b88c807SRodney W. Grimes arcn->sb.st_size = (off_t)(SHRT_EXT(hd->h_filesize_1)); 8824b88c807SRodney W. Grimes arcn->sb.st_size = (arcn->sb.st_size << 16) | 8834b88c807SRodney W. Grimes ((off_t)(SHRT_EXT(hd->h_filesize_2))); 8844b88c807SRodney W. Grimes nsz = (int)(SHRT_EXT(hd->h_namesize)); 8854b88c807SRodney W. Grimes } 8864b88c807SRodney W. Grimes arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime; 8874b88c807SRodney W. Grimes 8884b88c807SRodney W. Grimes /* 8894b88c807SRodney W. Grimes * check the file name size, if bogus give up. otherwise read the file 8904b88c807SRodney W. Grimes * name 8914b88c807SRodney W. Grimes */ 8924b88c807SRodney W. Grimes if (nsz < 2) 8934b88c807SRodney W. Grimes return(-1); 8944b88c807SRodney W. Grimes arcn->nlen = nsz - 1; 8954b88c807SRodney W. Grimes if (rd_nm(arcn, nsz) < 0) 8964b88c807SRodney W. Grimes return(-1); 8974b88c807SRodney W. Grimes 8984b88c807SRodney W. Grimes /* 89901c99176SUlrich Spörlein * header + file name are aligned to 2 byte boundaries, skip if needed 9004b88c807SRodney W. Grimes */ 9014b88c807SRodney W. Grimes if (rd_skip((off_t)(BCPIO_PAD(sizeof(HD_BCPIO) + nsz))) < 0) 9024b88c807SRodney W. Grimes return(-1); 9034b88c807SRodney W. Grimes 9044b88c807SRodney W. Grimes /* 9054b88c807SRodney W. Grimes * if not a link (or a file with no data), calculate pad size (for 9064b88c807SRodney W. Grimes * padding which follows the file data), clear the link name and return 9074b88c807SRodney W. Grimes */ 9084b88c807SRodney W. Grimes if (((arcn->sb.st_mode & C_IFMT) != C_ISLNK)||(arcn->sb.st_size == 0)){ 9094b88c807SRodney W. Grimes /* 9104b88c807SRodney W. Grimes * we have a valid header (not a link) 9114b88c807SRodney W. Grimes */ 9124b88c807SRodney W. Grimes arcn->pad = BCPIO_PAD(arcn->sb.st_size); 9134b88c807SRodney W. Grimes return(com_rd(arcn)); 9144b88c807SRodney W. Grimes } 9154b88c807SRodney W. Grimes 9164b88c807SRodney W. Grimes if ((rd_ln_nm(arcn) < 0) || 9174b88c807SRodney W. Grimes (rd_skip((off_t)(BCPIO_PAD(arcn->sb.st_size))) < 0)) 9184b88c807SRodney W. Grimes return(-1); 9194b88c807SRodney W. Grimes 9204b88c807SRodney W. Grimes /* 9214b88c807SRodney W. Grimes * we have a valid header (with a link) 9224b88c807SRodney W. Grimes */ 9234b88c807SRodney W. Grimes return(com_rd(arcn)); 9244b88c807SRodney W. Grimes } 9254b88c807SRodney W. Grimes 9264b88c807SRodney W. Grimes /* 9274b88c807SRodney W. Grimes * bcpio_endrd() 9284b88c807SRodney W. Grimes * no cleanup needed here, just return size of the trailer (for append) 9294b88c807SRodney W. Grimes * Return: 9304b88c807SRodney W. Grimes * size of trailer header in this format 9314b88c807SRodney W. Grimes */ 9324b88c807SRodney W. Grimes 9334b88c807SRodney W. Grimes off_t 9344b88c807SRodney W. Grimes bcpio_endrd(void) 9354b88c807SRodney W. Grimes { 9364b88c807SRodney W. Grimes return((off_t)(sizeof(HD_BCPIO) + sizeof(TRAILER) + 9374b88c807SRodney W. Grimes (BCPIO_PAD(sizeof(HD_BCPIO) + sizeof(TRAILER))))); 9384b88c807SRodney W. Grimes } 9394b88c807SRodney W. Grimes 9404b88c807SRodney W. Grimes /* 9414b88c807SRodney W. Grimes * bcpio_wr() 9424b88c807SRodney W. Grimes * copy the data in the ARCHD to buffer in old binary cpio format 9434b88c807SRodney W. Grimes * There is a real chance of field overflow with this critter. So we 94401c99176SUlrich Spörlein * always check that the conversion is ok. nobody in their right mind 94501c99176SUlrich Spörlein * should write an archive in this format... 9464b88c807SRodney W. Grimes * Return 9474b88c807SRodney W. Grimes * 0 if file has data to be written after the header, 1 if file has NO 9484b88c807SRodney W. Grimes * data to write after the header, -1 if archive write failed 9494b88c807SRodney W. Grimes */ 9504b88c807SRodney W. Grimes 9514b88c807SRodney W. Grimes int 952f789b261SWarner Losh bcpio_wr(ARCHD *arcn) 9534b88c807SRodney W. Grimes { 954f789b261SWarner Losh HD_BCPIO *hd; 955f789b261SWarner Losh int nsz; 956c65bb135SRuslan Ermilov HD_BCPIO hdblk; 9574b88c807SRodney W. Grimes off_t t_offt; 9584b88c807SRodney W. Grimes int t_int; 9594b88c807SRodney W. Grimes time_t t_timet; 9604b88c807SRodney W. Grimes 9614b88c807SRodney W. Grimes /* 9624b88c807SRodney W. Grimes * check and repair truncated device and inode fields in the cpio 9634b88c807SRodney W. Grimes * header 9644b88c807SRodney W. Grimes */ 9654b88c807SRodney W. Grimes if (map_dev(arcn, (u_long)BCPIO_MASK, (u_long)BCPIO_MASK) < 0) 9664b88c807SRodney W. Grimes return(-1); 9674b88c807SRodney W. Grimes 9684b88c807SRodney W. Grimes if ((arcn->type != PAX_BLK) && (arcn->type != PAX_CHR)) 9694b88c807SRodney W. Grimes arcn->sb.st_rdev = 0; 970c65bb135SRuslan Ermilov hd = &hdblk; 9714b88c807SRodney W. Grimes 9724b88c807SRodney W. Grimes switch(arcn->type) { 9734b88c807SRodney W. Grimes case PAX_CTG: 9744b88c807SRodney W. Grimes case PAX_REG: 9754b88c807SRodney W. Grimes case PAX_HRG: 9764b88c807SRodney W. Grimes /* 9774b88c807SRodney W. Grimes * caller will copy file data to the archive. tell him how 9784b88c807SRodney W. Grimes * much to pad. 9794b88c807SRodney W. Grimes */ 9804b88c807SRodney W. Grimes arcn->pad = BCPIO_PAD(arcn->sb.st_size); 9814b88c807SRodney W. Grimes hd->h_filesize_1[0] = CHR_WR_0(arcn->sb.st_size); 9824b88c807SRodney W. Grimes hd->h_filesize_1[1] = CHR_WR_1(arcn->sb.st_size); 9834b88c807SRodney W. Grimes hd->h_filesize_2[0] = CHR_WR_2(arcn->sb.st_size); 9844b88c807SRodney W. Grimes hd->h_filesize_2[1] = CHR_WR_3(arcn->sb.st_size); 9854b88c807SRodney W. Grimes t_offt = (off_t)(SHRT_EXT(hd->h_filesize_1)); 9864b88c807SRodney W. Grimes t_offt = (t_offt<<16) | ((off_t)(SHRT_EXT(hd->h_filesize_2))); 9874b88c807SRodney W. Grimes if (arcn->sb.st_size != t_offt) { 988778766feSKris Kennaway paxwarn(1,"File is too large for bcpio format %s", 9894b88c807SRodney W. Grimes arcn->org_name); 9904b88c807SRodney W. Grimes return(1); 9914b88c807SRodney W. Grimes } 9924b88c807SRodney W. Grimes break; 9934b88c807SRodney W. Grimes case PAX_SLK: 9944b88c807SRodney W. Grimes /* 9954b88c807SRodney W. Grimes * no file data for the caller to process, the file data has 9964b88c807SRodney W. Grimes * the size of the link 9974b88c807SRodney W. Grimes */ 9984b88c807SRodney W. Grimes arcn->pad = 0L; 9994b88c807SRodney W. Grimes hd->h_filesize_1[0] = CHR_WR_0(arcn->ln_nlen); 10004b88c807SRodney W. Grimes hd->h_filesize_1[1] = CHR_WR_1(arcn->ln_nlen); 10014b88c807SRodney W. Grimes hd->h_filesize_2[0] = CHR_WR_2(arcn->ln_nlen); 10024b88c807SRodney W. Grimes hd->h_filesize_2[1] = CHR_WR_3(arcn->ln_nlen); 10034b88c807SRodney W. Grimes t_int = (int)(SHRT_EXT(hd->h_filesize_1)); 10044b88c807SRodney W. Grimes t_int = (t_int << 16) | ((int)(SHRT_EXT(hd->h_filesize_2))); 10054b88c807SRodney W. Grimes if (arcn->ln_nlen != t_int) 10064b88c807SRodney W. Grimes goto out; 10074b88c807SRodney W. Grimes break; 10084b88c807SRodney W. Grimes default: 10094b88c807SRodney W. Grimes /* 10104b88c807SRodney W. Grimes * no file data for the caller to process 10114b88c807SRodney W. Grimes */ 10124b88c807SRodney W. Grimes arcn->pad = 0L; 10134b88c807SRodney W. Grimes hd->h_filesize_1[0] = (char)0; 10144b88c807SRodney W. Grimes hd->h_filesize_1[1] = (char)0; 10154b88c807SRodney W. Grimes hd->h_filesize_2[0] = (char)0; 10164b88c807SRodney W. Grimes hd->h_filesize_2[1] = (char)0; 10174b88c807SRodney W. Grimes break; 10184b88c807SRodney W. Grimes } 10194b88c807SRodney W. Grimes 10204b88c807SRodney W. Grimes /* 10214b88c807SRodney W. Grimes * build up the rest of the fields 10224b88c807SRodney W. Grimes */ 10234b88c807SRodney W. Grimes hd->h_magic[0] = CHR_WR_2(MAGIC); 10244b88c807SRodney W. Grimes hd->h_magic[1] = CHR_WR_3(MAGIC); 10254b88c807SRodney W. Grimes hd->h_dev[0] = CHR_WR_2(arcn->sb.st_dev); 10264b88c807SRodney W. Grimes hd->h_dev[1] = CHR_WR_3(arcn->sb.st_dev); 10274b88c807SRodney W. Grimes if (arcn->sb.st_dev != (dev_t)(SHRT_EXT(hd->h_dev))) 10284b88c807SRodney W. Grimes goto out; 10294b88c807SRodney W. Grimes hd->h_ino[0] = CHR_WR_2(arcn->sb.st_ino); 10304b88c807SRodney W. Grimes hd->h_ino[1] = CHR_WR_3(arcn->sb.st_ino); 10314b88c807SRodney W. Grimes if (arcn->sb.st_ino != (ino_t)(SHRT_EXT(hd->h_ino))) 10324b88c807SRodney W. Grimes goto out; 10334b88c807SRodney W. Grimes hd->h_mode[0] = CHR_WR_2(arcn->sb.st_mode); 10344b88c807SRodney W. Grimes hd->h_mode[1] = CHR_WR_3(arcn->sb.st_mode); 10354b88c807SRodney W. Grimes if (arcn->sb.st_mode != (mode_t)(SHRT_EXT(hd->h_mode))) 10364b88c807SRodney W. Grimes goto out; 10374b88c807SRodney W. Grimes hd->h_uid[0] = CHR_WR_2(arcn->sb.st_uid); 10384b88c807SRodney W. Grimes hd->h_uid[1] = CHR_WR_3(arcn->sb.st_uid); 10394b88c807SRodney W. Grimes if (arcn->sb.st_uid != (uid_t)(SHRT_EXT(hd->h_uid))) 10404b88c807SRodney W. Grimes goto out; 10414b88c807SRodney W. Grimes hd->h_gid[0] = CHR_WR_2(arcn->sb.st_gid); 10424b88c807SRodney W. Grimes hd->h_gid[1] = CHR_WR_3(arcn->sb.st_gid); 10434b88c807SRodney W. Grimes if (arcn->sb.st_gid != (gid_t)(SHRT_EXT(hd->h_gid))) 10444b88c807SRodney W. Grimes goto out; 10454b88c807SRodney W. Grimes hd->h_nlink[0] = CHR_WR_2(arcn->sb.st_nlink); 10464b88c807SRodney W. Grimes hd->h_nlink[1] = CHR_WR_3(arcn->sb.st_nlink); 10474b88c807SRodney W. Grimes if (arcn->sb.st_nlink != (nlink_t)(SHRT_EXT(hd->h_nlink))) 10484b88c807SRodney W. Grimes goto out; 10494b88c807SRodney W. Grimes hd->h_rdev[0] = CHR_WR_2(arcn->sb.st_rdev); 10504b88c807SRodney W. Grimes hd->h_rdev[1] = CHR_WR_3(arcn->sb.st_rdev); 10514b88c807SRodney W. Grimes if (arcn->sb.st_rdev != (dev_t)(SHRT_EXT(hd->h_rdev))) 10524b88c807SRodney W. Grimes goto out; 10534b88c807SRodney W. Grimes hd->h_mtime_1[0] = CHR_WR_0(arcn->sb.st_mtime); 10544b88c807SRodney W. Grimes hd->h_mtime_1[1] = CHR_WR_1(arcn->sb.st_mtime); 10554b88c807SRodney W. Grimes hd->h_mtime_2[0] = CHR_WR_2(arcn->sb.st_mtime); 10564b88c807SRodney W. Grimes hd->h_mtime_2[1] = CHR_WR_3(arcn->sb.st_mtime); 10574b88c807SRodney W. Grimes t_timet = (time_t)(SHRT_EXT(hd->h_mtime_1)); 10584b88c807SRodney W. Grimes t_timet = (t_timet << 16) | ((time_t)(SHRT_EXT(hd->h_mtime_2))); 10594b88c807SRodney W. Grimes if (arcn->sb.st_mtime != t_timet) 10604b88c807SRodney W. Grimes goto out; 10614b88c807SRodney W. Grimes nsz = arcn->nlen + 1; 10624b88c807SRodney W. Grimes hd->h_namesize[0] = CHR_WR_2(nsz); 10634b88c807SRodney W. Grimes hd->h_namesize[1] = CHR_WR_3(nsz); 10644b88c807SRodney W. Grimes if (nsz != (int)(SHRT_EXT(hd->h_namesize))) 10654b88c807SRodney W. Grimes goto out; 10664b88c807SRodney W. Grimes 10674b88c807SRodney W. Grimes /* 10684b88c807SRodney W. Grimes * write the header, the file name and padding as required. 10694b88c807SRodney W. Grimes */ 1070c65bb135SRuslan Ermilov if ((wr_rdbuf((char *)&hdblk, (int)sizeof(HD_BCPIO)) < 0) || 10714b88c807SRodney W. Grimes (wr_rdbuf(arcn->name, nsz) < 0) || 10724b88c807SRodney W. Grimes (wr_skip((off_t)(BCPIO_PAD(sizeof(HD_BCPIO) + nsz))) < 0)) { 1073778766feSKris Kennaway paxwarn(1, "Could not write bcpio header for %s", arcn->org_name); 10744b88c807SRodney W. Grimes return(-1); 10754b88c807SRodney W. Grimes } 10764b88c807SRodney W. Grimes 10774b88c807SRodney W. Grimes /* 10784b88c807SRodney W. Grimes * if we have file data, tell the caller we are done 10794b88c807SRodney W. Grimes */ 10804b88c807SRodney W. Grimes if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG) || 10814b88c807SRodney W. Grimes (arcn->type == PAX_HRG)) 10824b88c807SRodney W. Grimes return(0); 10834b88c807SRodney W. Grimes 10844b88c807SRodney W. Grimes /* 10854b88c807SRodney W. Grimes * if we are not a link, tell the caller we are done, go to next file 10864b88c807SRodney W. Grimes */ 10874b88c807SRodney W. Grimes if (arcn->type != PAX_SLK) 10884b88c807SRodney W. Grimes return(1); 10894b88c807SRodney W. Grimes 10904b88c807SRodney W. Grimes /* 10914b88c807SRodney W. Grimes * write the link name, tell the caller we are done. 10924b88c807SRodney W. Grimes */ 10934b88c807SRodney W. Grimes if ((wr_rdbuf(arcn->ln_name, arcn->ln_nlen) < 0) || 10944b88c807SRodney W. Grimes (wr_skip((off_t)(BCPIO_PAD(arcn->ln_nlen))) < 0)) { 1095778766feSKris Kennaway paxwarn(1,"Could not write bcpio link name for %s",arcn->org_name); 10964b88c807SRodney W. Grimes return(-1); 10974b88c807SRodney W. Grimes } 10984b88c807SRodney W. Grimes return(1); 10994b88c807SRodney W. Grimes 11004b88c807SRodney W. Grimes out: 11014b88c807SRodney W. Grimes /* 11024b88c807SRodney W. Grimes * header field is out of range 11034b88c807SRodney W. Grimes */ 1104778766feSKris Kennaway paxwarn(1,"Bcpio header field is too small for file %s", arcn->org_name); 11054b88c807SRodney W. Grimes return(1); 11064b88c807SRodney W. Grimes } 1107