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