157198Smuller /*- 257198Smuller * Copyright (c) 1992 Keith Muller. 357198Smuller * Copyright (c) 1992 The Regents of the University of California. 457198Smuller * All rights reserved. 557198Smuller * 657198Smuller * This code is derived from software contributed to Berkeley by 757198Smuller * Keith Muller of the University of California, San Diego. 857198Smuller * 957198Smuller * %sccs.include.redist.c% 1057198Smuller */ 1157198Smuller 1257198Smuller #ifndef lint 13*57499Smuller static char sccsid[] = "@(#)cpio.c 1.2 (Berkeley) 01/12/93"; 1457198Smuller #endif /* not lint */ 1557198Smuller 1657198Smuller #include <sys/types.h> 1757198Smuller #include <sys/time.h> 1857198Smuller #include <sys/stat.h> 1957198Smuller #include <sys/param.h> 2057198Smuller #include <string.h> 2157198Smuller #include <ctype.h> 2257198Smuller #include <stdio.h> 2357198Smuller #include <unistd.h> 2457198Smuller #include <stdlib.h> 2557198Smuller #include "pax.h" 2657198Smuller #include "cpio.h" 2757198Smuller #include "extern.h" 28*57499Smuller 2957198Smuller static int rd_nm __P((register ARCHD *, int)); 3057198Smuller static int rd_ln_nm __P((register ARCHD *)); 3157198Smuller static int com_rd __P((register ARCHD *)); 3257198Smuller 3357198Smuller /* 3457198Smuller * Routines which support the different cpio versions 3557198Smuller */ 3657198Smuller 3757198Smuller static int swp_head; /* binary cpio header byte swap */ 3857198Smuller 3957198Smuller /* 4057198Smuller * Routines common to all versions of cpio 4157198Smuller */ 4257198Smuller 4357198Smuller /* 4457198Smuller * cpio_strd() 4557198Smuller * Fire up the hard link detection code 4657198Smuller * Return: 4757198Smuller * 0 if ok -1 otherwise (the return values of lnk_start()) 4857198Smuller */ 4957198Smuller 5057198Smuller #if __STDC__ 5157198Smuller int 5257198Smuller cpio_strd(void) 5357198Smuller #else 5457198Smuller int 5557198Smuller cpio_strd() 5657198Smuller #endif 5757198Smuller { 5857198Smuller return(lnk_start()); 5957198Smuller } 6057198Smuller 6157198Smuller /* 6257198Smuller * cpio_trail() 6357198Smuller * Called to determine if a header block is a valid trailer. We are 6457198Smuller * passed the block, the in_sync flag (which tells us we are in resync 6557198Smuller * mode; looking for a valid header), and cnt (which starts at zero) 6657198Smuller * which is used to count the number of empty blocks we have seen so far. 6757198Smuller * Return: 6857198Smuller * 0 if a valid trailer, -1 if not a valid trailer, 6957198Smuller */ 7057198Smuller 7157198Smuller #if __STDC__ 7257198Smuller int 7357198Smuller cpio_trail(register ARCHD *arcn) 7457198Smuller #else 7557198Smuller int 7657198Smuller cpio_trail(arcn) 7757198Smuller register ARCHD *arcn; 7857198Smuller #endif 7957198Smuller { 8057198Smuller /* 8157198Smuller * look for trailer id in file we are about to process 8257198Smuller */ 8357198Smuller if ((strcmp(arcn->name, TRAILER) == 0) && (arcn->sb.st_size == 0)) 8457198Smuller return(0); 8557198Smuller return(-1); 8657198Smuller } 8757198Smuller 8857198Smuller /* 8957198Smuller * com_rd() 9057198Smuller * operations common to all cpio read functions. 9157198Smuller * Return: 9257198Smuller * 0 9357198Smuller */ 9457198Smuller 9557198Smuller #if __STDC__ 9657198Smuller static int 9757198Smuller com_rd(register ARCHD *arcn) 9857198Smuller #else 9957198Smuller static int 10057198Smuller com_rd(arcn) 10157198Smuller register ARCHD *arcn; 10257198Smuller #endif 10357198Smuller { 10457198Smuller arcn->skip = 0; 10557198Smuller arcn->pat = NULL; 10657198Smuller arcn->org_name = arcn->name; 10757198Smuller switch(arcn->sb.st_mode & C_IFMT) { 10857198Smuller case C_ISFIFO: 10957198Smuller arcn->type = PAX_FIF; 11057198Smuller break; 11157198Smuller case C_ISDIR: 11257198Smuller arcn->type = PAX_DIR; 11357198Smuller break; 11457198Smuller case C_ISBLK: 11557198Smuller arcn->type = PAX_BLK; 11657198Smuller break; 11757198Smuller case C_ISCHR: 11857198Smuller arcn->type = PAX_CHR; 11957198Smuller break; 12057198Smuller case C_ISLNK: 12157198Smuller arcn->type = PAX_SLK; 12257198Smuller break; 12357198Smuller case C_ISOCK: 12457198Smuller arcn->type = PAX_SCK; 12557198Smuller break; 12657198Smuller case C_ISCTG: 12757198Smuller case C_ISREG: 12857198Smuller default: 12957198Smuller /* 13057198Smuller * we have file data, set up skip (pad is set in the format 13157198Smuller * specific sections) 13257198Smuller */ 13357198Smuller arcn->sb.st_mode = (arcn->sb.st_mode & 0xfff) | C_ISREG; 13457198Smuller arcn->type = PAX_REG; 13557198Smuller arcn->skip = arcn->sb.st_size; 13657198Smuller break; 13757198Smuller } 13857198Smuller if (chk_lnk(arcn) < 0) 13957198Smuller return(-1); 14057198Smuller return(0); 14157198Smuller } 14257198Smuller 14357198Smuller /* 14457198Smuller * cpio_end_wr() 14557198Smuller * write the special file with the name trailer in the proper format 14657198Smuller * Return: 14757198Smuller * result of the write of the trailer from the cpio specific write func 14857198Smuller */ 14957198Smuller 15057198Smuller #if __STDC__ 15157198Smuller int 15257198Smuller cpio_endwr(void) 15357198Smuller #else 15457198Smuller int 15557198Smuller cpio_endwr() 15657198Smuller #endif 15757198Smuller { 15857198Smuller ARCHD last; 15957198Smuller 16057198Smuller /* 16157198Smuller * create a trailer request and call the proper format write function 16257198Smuller */ 16357198Smuller bzero((char *)&last, sizeof(last)); 16457198Smuller last.nlen = sizeof(TRAILER) - 1; 16557198Smuller last.type = PAX_REG; 16657198Smuller last.sb.st_nlink = 1; 16757198Smuller (void)strcpy(last.name, TRAILER); 16857198Smuller return((*frmt->wr)(&last)); 16957198Smuller } 17057198Smuller 17157198Smuller /* 17257198Smuller * rd_nam() 17357198Smuller * read in the file name which follows the cpio header 17457198Smuller * Return: 17557198Smuller * 0 if ok, -1 otherwise 17657198Smuller */ 17757198Smuller 17857198Smuller #if __STDC__ 17957198Smuller static int 18057198Smuller rd_nm(register ARCHD *arcn, int nsz) 18157198Smuller #else 18257198Smuller static int 18357198Smuller rd_nm(arcn, nsz) 18457198Smuller register ARCHD *arcn; 18557198Smuller int nsz; 18657198Smuller #endif 18757198Smuller { 18857198Smuller /* 18957198Smuller * do not even try bogus values 19057198Smuller */ 19157198Smuller if ((nsz == 0) || (nsz > sizeof(arcn->name))) { 19257198Smuller warn(1, "Cpio file name length %d is out of range", nsz); 19357198Smuller return(-1); 19457198Smuller } 19557198Smuller 19657198Smuller /* 19757198Smuller * read the name and make sure it is not empty and is \0 terminated 19857198Smuller */ 19957198Smuller if ((rd_wrbuf(arcn->name,nsz) != nsz) || (arcn->name[nsz-1] != '\0') || 20057198Smuller (arcn->name[0] == '\0')) { 20157198Smuller warn(1, "Cpio file name in header is corrupted"); 20257198Smuller return(-1); 20357198Smuller } 20457198Smuller return(0); 20557198Smuller } 20657198Smuller 20757198Smuller /* 20857198Smuller * rd_ln_nm() 20957198Smuller * read in the link name for a file with links. The link name is stored 21057198Smuller * like file data (and is NOT \0 terminated!) 21157198Smuller * Return: 21257198Smuller * 0 if ok, -1 otherwise 21357198Smuller */ 21457198Smuller 21557198Smuller #if __STDC__ 21657198Smuller static int 21757198Smuller rd_ln_nm(register ARCHD *arcn) 21857198Smuller #else 21957198Smuller static int 22057198Smuller rd_ln_nm(arcn) 22157198Smuller register ARCHD *arcn; 22257198Smuller #endif 22357198Smuller { 22457198Smuller /* 22557198Smuller * check the length specified for bogus values 22657198Smuller */ 22757198Smuller if ((arcn->sb.st_size == 0) || 22857198Smuller (arcn->sb.st_size >= sizeof(arcn->ln_name))) { 22957198Smuller # ifdef NET2_STAT 23057198Smuller warn(1, "Cpio link name length is invalid: %lu", 23157198Smuller arcn->sb.st_size); 23257198Smuller # else 23357198Smuller warn(1, "Cpio link name length is invalid: %qu", 23457198Smuller arcn->sb.st_size); 23557198Smuller # endif 23657198Smuller return(-1); 23757198Smuller } 23857198Smuller 23957198Smuller /* 24057198Smuller * read in the link name and \0 terminate it 24157198Smuller */ 24257198Smuller if (rd_wrbuf(arcn->ln_name, (int)arcn->sb.st_size) != 24357198Smuller (int)arcn->sb.st_size) { 24457198Smuller warn(1, "Cpio link name read error"); 24557198Smuller return(-1); 24657198Smuller } 24757198Smuller arcn->ln_nlen = arcn->sb.st_size; 24857198Smuller arcn->ln_name[arcn->ln_nlen] = '\0'; 24957198Smuller 25057198Smuller /* 25157198Smuller * watch out for those empty link names 25257198Smuller */ 25357198Smuller if (arcn->ln_name[0] == '\0') { 25457198Smuller warn(1, "Cpio link name is corrupt"); 25557198Smuller return(-1); 25657198Smuller } 25757198Smuller return(0); 25857198Smuller } 25957198Smuller 26057198Smuller /* 26157198Smuller * Routines common to the extended byte oriented cpio format 26257198Smuller */ 26357198Smuller 26457198Smuller /* 26557198Smuller * cpio_id() 26657198Smuller * determine if a block given to us is a valid extended byte oriented 26757198Smuller * cpio header 26857198Smuller * Return: 26957198Smuller * 0 if a valid header, -1 otherwise 27057198Smuller */ 27157198Smuller 27257198Smuller #if __STDC__ 27357198Smuller int 27457198Smuller cpio_id(char *blk, int size) 27557198Smuller #else 27657198Smuller int 27757198Smuller cpio_id(blk, size) 27857198Smuller char *blk; 27957198Smuller int size; 28057198Smuller #endif 28157198Smuller { 28257198Smuller if ((size < sizeof(HD_CPIO)) || 28357198Smuller (strncmp(blk, AMAGIC, sizeof(AMAGIC) - 1) != 0)) 28457198Smuller return(-1); 28557198Smuller return(0); 28657198Smuller } 28757198Smuller 28857198Smuller /* 28957198Smuller * cpio_rd() 29057198Smuller * determine if a buffer is a byte oriented extended cpio archive entry. 29157198Smuller * convert and store the values in the ARCHD parameter. 29257198Smuller * Return: 29357198Smuller * 0 if a valid header, -1 otherwise. 29457198Smuller */ 29557198Smuller 29657198Smuller #if __STDC__ 29757198Smuller int 29857198Smuller cpio_rd(register ARCHD *arcn, register char *buf) 29957198Smuller #else 30057198Smuller int 30157198Smuller cpio_rd(arcn, buf) 30257198Smuller register ARCHD *arcn; 30357198Smuller register char *buf; 30457198Smuller #endif 30557198Smuller { 30657198Smuller register int nsz; 30757198Smuller register HD_CPIO *hd; 30857198Smuller 30957198Smuller /* 31057198Smuller * check that this is a valid header, if not return -1 31157198Smuller */ 31257198Smuller if (cpio_id(buf, sizeof(HD_CPIO)) < 0) 31357198Smuller return(-1); 31457198Smuller hd = (HD_CPIO *)buf; 31557198Smuller 31657198Smuller /* 31757198Smuller * byte oriented cpio (posix) does not have padding! extract the octal 31857198Smuller * ascii fields from the header 31957198Smuller */ 32057198Smuller arcn->pad = 0L; 32157198Smuller arcn->sb.st_dev = (dev_t)asc_ul(hd->c_dev, sizeof(hd->c_dev), OCT); 32257198Smuller arcn->sb.st_ino = (ino_t)asc_ul(hd->c_ino, sizeof(hd->c_ino), OCT); 32357198Smuller arcn->sb.st_mode = (mode_t)asc_ul(hd->c_mode, sizeof(hd->c_mode), OCT); 32457198Smuller arcn->sb.st_uid = (uid_t)asc_ul(hd->c_uid, sizeof(hd->c_uid), OCT); 32557198Smuller arcn->sb.st_gid = (gid_t)asc_ul(hd->c_gid, sizeof(hd->c_gid), OCT); 32657198Smuller arcn->sb.st_nlink = (nlink_t)asc_ul(hd->c_nlink, sizeof(hd->c_nlink), 32757198Smuller OCT); 32857198Smuller arcn->sb.st_rdev = (dev_t)asc_ul(hd->c_rdev, sizeof(hd->c_rdev), OCT); 32957198Smuller arcn->sb.st_mtime = (time_t)asc_ul(hd->c_mtime, sizeof(hd->c_mtime), 33057198Smuller OCT); 331*57499Smuller arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime; 33257198Smuller # ifdef NET2_STAT 33357198Smuller arcn->sb.st_size = (off_t)asc_ul(hd->c_filesize,sizeof(hd->c_filesize), 33457198Smuller OCT); 33557198Smuller # else 33657198Smuller arcn->sb.st_size = (off_t)asc_uqd(hd->c_filesize,sizeof(hd->c_filesize), 33757198Smuller OCT); 33857198Smuller # endif 33957198Smuller 34057198Smuller /* 34157198Smuller * check name size and if valid, read in the name of this entry (name 34257198Smuller * follows header in the archive) 34357198Smuller */ 34457198Smuller if ((nsz = (int)asc_ul(hd->c_namesize,sizeof(hd->c_namesize),OCT)) < 2) 34557198Smuller return(-1); 34657198Smuller arcn->nlen = nsz - 1; 34757198Smuller if (rd_nm(arcn, nsz) < 0) 34857198Smuller return(-1); 34957198Smuller 35057198Smuller if (((arcn->sb.st_mode&C_IFMT) != C_ISLNK)||(arcn->sb.st_size == 0)) { 35157198Smuller /* 35257198Smuller * no link name to read for this file 35357198Smuller */ 35457198Smuller arcn->ln_nlen = 0; 35557198Smuller arcn->ln_name[0] = '\0'; 35657198Smuller return(com_rd(arcn)); 35757198Smuller } 35857198Smuller 35957198Smuller /* 36057198Smuller * check link name size and read in the link name. Link names are 36157198Smuller * stored like file data. 36257198Smuller */ 36357198Smuller if (rd_ln_nm(arcn) < 0) 36457198Smuller return(-1); 36557198Smuller 36657198Smuller /* 36757198Smuller * we have a valid header (with a link) 36857198Smuller */ 36957198Smuller return(com_rd(arcn)); 37057198Smuller } 37157198Smuller 37257198Smuller /* 37357198Smuller * cpio_endrd() 37457198Smuller * no cleanup needed here, just return size of the trailer (for append) 37557198Smuller * Return: 37657198Smuller * size of trailer header in this format 37757198Smuller */ 37857198Smuller 37957198Smuller #if __STDC__ 38057198Smuller off_t 38157198Smuller cpio_endrd(void) 38257198Smuller #else 38357198Smuller off_t 38457198Smuller cpio_endrd() 38557198Smuller #endif 38657198Smuller { 38757198Smuller return((off_t)(sizeof(HD_CPIO) + sizeof(TRAILER))); 38857198Smuller } 38957198Smuller 39057198Smuller /* 39157198Smuller * cpio_stwr() 39257198Smuller * start up the device mapping table 39357198Smuller * Return: 39457198Smuller * 0 if ok, -1 otherwise (what dev_start() returns) 39557198Smuller */ 39657198Smuller 39757198Smuller #if __STDC__ 39857198Smuller int 39957198Smuller cpio_stwr(void) 40057198Smuller #else 40157198Smuller int 40257198Smuller cpio_stwr() 40357198Smuller #endif 40457198Smuller { 40557198Smuller return(dev_start()); 40657198Smuller } 40757198Smuller 40857198Smuller /* 40957198Smuller * cpio_wr() 41057198Smuller * copy the data in the ARCHD to buffer in extended byte oriented cpio 41157198Smuller * format. 41257198Smuller * Return 41357198Smuller * 0 if file has data to be written after the header, 1 if file has NO 41457198Smuller * data to write after the header, -1 if archive write failed 41557198Smuller */ 41657198Smuller 41757198Smuller #if __STDC__ 41857198Smuller int 41957198Smuller cpio_wr(register ARCHD *arcn) 42057198Smuller #else 42157198Smuller int 42257198Smuller cpio_wr(arcn) 42357198Smuller register ARCHD *arcn; 42457198Smuller #endif 42557198Smuller { 42657198Smuller register HD_CPIO *hd; 42757198Smuller register int nsz; 42857198Smuller char hdblk[sizeof(HD_CPIO)]; 42957198Smuller 43057198Smuller /* 43157198Smuller * check and repair truncated device and inode fields in the header 43257198Smuller */ 43357198Smuller if (map_dev(arcn, (u_long)CPIO_MASK, (u_long)CPIO_MASK) < 0) 43457198Smuller return(-1); 43557198Smuller 43657198Smuller arcn->pad = 0L; 43757198Smuller nsz = arcn->nlen + 1; 43857198Smuller hd = (HD_CPIO *)hdblk; 43957198Smuller if ((arcn->type != PAX_BLK) && (arcn->type != PAX_CHR)) 44057198Smuller arcn->sb.st_rdev = 0; 44157198Smuller 44257198Smuller switch(arcn->type) { 44357198Smuller case PAX_CTG: 44457198Smuller case PAX_REG: 44557198Smuller case PAX_HRG: 44657198Smuller /* 44757198Smuller * set data size for file data 44857198Smuller */ 44957198Smuller # ifdef NET2_STAT 45057198Smuller if (ul_asc((u_long)arcn->sb.st_size, hd->c_filesize, 45157198Smuller sizeof(hd->c_filesize), OCT)) { 45257198Smuller # else 45357198Smuller if (uqd_asc((u_quad_t)arcn->sb.st_size, hd->c_filesize, 45457198Smuller sizeof(hd->c_filesize), OCT)) { 45557198Smuller # endif 45657198Smuller warn(1,"File is too large for cpio format %s", 45757198Smuller arcn->org_name); 45857198Smuller return(1); 45957198Smuller } 46057198Smuller break; 46157198Smuller case PAX_SLK: 46257198Smuller /* 46357198Smuller * set data size to hold link name 46457198Smuller */ 46557198Smuller if (ul_asc((u_long)arcn->ln_nlen, hd->c_filesize, 46657198Smuller sizeof(hd->c_filesize), OCT)) 46757198Smuller goto out; 46857198Smuller break; 46957198Smuller default: 47057198Smuller /* 47157198Smuller * all other file types have no file data 47257198Smuller */ 47357198Smuller if (ul_asc((u_long)0, hd->c_filesize, sizeof(hd->c_filesize), 47457198Smuller OCT)) 47557198Smuller goto out; 47657198Smuller break; 47757198Smuller } 47857198Smuller 47957198Smuller /* 48057198Smuller * copy the values to the header using octal ascii 48157198Smuller */ 48257198Smuller if (ul_asc((u_long)MAGIC, hd->c_magic, sizeof(hd->c_magic), OCT) || 48357198Smuller ul_asc((u_long)arcn->sb.st_dev, hd->c_dev, sizeof(hd->c_dev), 48457198Smuller OCT) || 48557198Smuller ul_asc((u_long)arcn->sb.st_ino, hd->c_ino, sizeof(hd->c_ino), 48657198Smuller OCT) || 48757198Smuller ul_asc((u_long)arcn->sb.st_mode, hd->c_mode, sizeof(hd->c_mode), 48857198Smuller OCT) || 48957198Smuller ul_asc((u_long)arcn->sb.st_uid, hd->c_uid, sizeof(hd->c_uid), 49057198Smuller OCT) || 49157198Smuller ul_asc((u_long)arcn->sb.st_gid, hd->c_gid, sizeof(hd->c_gid), 49257198Smuller OCT) || 49357198Smuller ul_asc((u_long)arcn->sb.st_nlink, hd->c_nlink, sizeof(hd->c_nlink), 49457198Smuller OCT) || 49557198Smuller ul_asc((u_long)arcn->sb.st_rdev, hd->c_rdev, sizeof(hd->c_rdev), 49657198Smuller OCT) || 49757198Smuller ul_asc((u_long)arcn->sb.st_mtime,hd->c_mtime,sizeof(hd->c_mtime), 49857198Smuller OCT) || 49957198Smuller ul_asc((u_long)nsz, hd->c_namesize, sizeof(hd->c_namesize), OCT)) 50057198Smuller goto out; 50157198Smuller 50257198Smuller /* 50357198Smuller * write the file name to the archive 50457198Smuller */ 50557198Smuller if ((wr_rdbuf(hdblk, (int)sizeof(HD_CPIO)) < 0) || 50657198Smuller (wr_rdbuf(arcn->name, nsz) < 0)) { 50757198Smuller warn(1, "Unable to write cpio header for %s", arcn->org_name); 50857198Smuller return(-1); 50957198Smuller } 51057198Smuller 51157198Smuller /* 51257198Smuller * if this file has data, we are done. The caller will write the file 51357198Smuller * data, if we are link tell caller we are done, go to next file 51457198Smuller */ 51557198Smuller if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG) || 51657198Smuller (arcn->type == PAX_HRG)) 51757198Smuller return(0); 51857198Smuller if (arcn->type != PAX_SLK) 51957198Smuller return(1); 52057198Smuller 52157198Smuller /* 52257198Smuller * write the link name to the archive, tell the caller to go to the 52357198Smuller * next file as we are done. 52457198Smuller */ 52557198Smuller if (wr_rdbuf(arcn->ln_name, arcn->ln_nlen) < 0) { 52657198Smuller warn(1,"Unable to write cpio link name for %s",arcn->org_name); 52757198Smuller return(-1); 52857198Smuller } 52957198Smuller return(1); 53057198Smuller 53157198Smuller out: 53257198Smuller /* 53357198Smuller * header field is out of range 53457198Smuller */ 53557198Smuller warn(1, "Cpio header field is too small to store file %s", 53657198Smuller arcn->org_name); 53757198Smuller return(1); 53857198Smuller } 53957198Smuller 54057198Smuller /* 54157198Smuller * Routines common to the system VR4 version of cpio (with/without file CRC) 54257198Smuller */ 54357198Smuller 54457198Smuller /* 54557198Smuller * vcpio_id() 54657198Smuller * determine if a block given to us is a valid system VR4 cpio header 54757198Smuller * WITHOUT crc. WATCH it the magic cookies are in OCTAL, the header 54857198Smuller * uses HEX 54957198Smuller * Return: 55057198Smuller * 0 if a valid header, -1 otherwise 55157198Smuller */ 55257198Smuller 55357198Smuller #if __STDC__ 55457198Smuller int 55557198Smuller vcpio_id(char *blk, int size) 55657198Smuller #else 55757198Smuller int 55857198Smuller vcpio_id(blk, size) 55957198Smuller char *blk; 56057198Smuller int size; 56157198Smuller #endif 56257198Smuller { 56357198Smuller if ((size < sizeof(HD_VCPIO)) || 56457198Smuller (strncmp(blk, AVMAGIC, sizeof(AVMAGIC) - 1) != 0)) 56557198Smuller return(-1); 56657198Smuller return(0); 56757198Smuller } 56857198Smuller 56957198Smuller /* 57057198Smuller * crc_id() 57157198Smuller * determine if a block given to us is a valid system VR4 cpio header 57257198Smuller * WITH crc. WATCH it the magic cookies are in OCTAL the header uses HEX 57357198Smuller * Return: 57457198Smuller * 0 if a valid header, -1 otherwise 57557198Smuller */ 57657198Smuller 57757198Smuller #if __STDC__ 57857198Smuller int 57957198Smuller crc_id(char *blk, int size) 58057198Smuller #else 58157198Smuller int 58257198Smuller crc_id(blk, size) 58357198Smuller char *blk; 58457198Smuller int size; 58557198Smuller #endif 58657198Smuller { 58757198Smuller if ((size < sizeof(HD_VCPIO)) || 58857198Smuller (strncmp(blk, AVCMAGIC, sizeof(AVCMAGIC) - 1) != 0)) 58957198Smuller return(-1); 59057198Smuller return(0); 59157198Smuller } 59257198Smuller 59357198Smuller /* 59457198Smuller * crc_strd() 59557198Smuller w set file data CRC calculations. Fire up the hard link detection code 59657198Smuller * Return: 59757198Smuller * 0 if ok -1 otherwise (the return values of lnk_start()) 59857198Smuller */ 59957198Smuller 60057198Smuller #if __STDC__ 60157198Smuller int 60257198Smuller crc_strd(void) 60357198Smuller #else 60457198Smuller int 60557198Smuller crc_strd() 60657198Smuller #endif 60757198Smuller { 60857198Smuller docrc = 1; 60957198Smuller return(lnk_start()); 61057198Smuller } 61157198Smuller 61257198Smuller /* 61357198Smuller * vcpio_rd() 61457198Smuller * determine if a buffer is a system VR4 archive entry. (with/without CRC) 61557198Smuller * convert and store the values in the ARCHD parameter. 61657198Smuller * Return: 61757198Smuller * 0 if a valid header, -1 otherwise. 61857198Smuller */ 61957198Smuller 62057198Smuller #if __STDC__ 62157198Smuller int 62257198Smuller vcpio_rd(register ARCHD *arcn, register char *buf) 62357198Smuller #else 62457198Smuller int 62557198Smuller vcpio_rd(arcn, buf) 62657198Smuller register ARCHD *arcn; 62757198Smuller register char *buf; 62857198Smuller #endif 62957198Smuller { 63057198Smuller register HD_VCPIO *hd; 63157198Smuller dev_t devminor; 63257198Smuller dev_t devmajor; 63357198Smuller register int nsz; 63457198Smuller 63557198Smuller /* 63657198Smuller * during the id phase it was determined if we were using CRC, use the 63757198Smuller * proper id routine. 63857198Smuller */ 63957198Smuller if (docrc) { 64057198Smuller if (crc_id(buf, sizeof(HD_VCPIO)) < 0) 64157198Smuller return(-1); 64257198Smuller } else { 64357198Smuller if (vcpio_id(buf, sizeof(HD_VCPIO)) < 0) 64457198Smuller return(-1); 64557198Smuller } 64657198Smuller 64757198Smuller hd = (HD_VCPIO *)buf; 64857198Smuller arcn->pad = 0L; 64957198Smuller 65057198Smuller /* 65157198Smuller * extract the hex ascii fields from the header 65257198Smuller */ 65357198Smuller arcn->sb.st_ino = (ino_t)asc_ul(hd->c_ino, sizeof(hd->c_ino), HEX); 65457198Smuller arcn->sb.st_mode = (mode_t)asc_ul(hd->c_mode, sizeof(hd->c_mode), HEX); 65557198Smuller arcn->sb.st_uid = (uid_t)asc_ul(hd->c_uid, sizeof(hd->c_uid), HEX); 65657198Smuller arcn->sb.st_gid = (gid_t)asc_ul(hd->c_gid, sizeof(hd->c_gid), HEX); 65757198Smuller arcn->sb.st_mtime = (time_t)asc_ul(hd->c_mtime,sizeof(hd->c_mtime),HEX); 658*57499Smuller arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime; 65957198Smuller # ifdef NET2_STAT 66057198Smuller arcn->sb.st_size = (off_t)asc_ul(hd->c_filesize, 66157198Smuller sizeof(hd->c_filesize), HEX); 66257198Smuller # else 66357198Smuller arcn->sb.st_size = (off_t)asc_uqd(hd->c_filesize, 66457198Smuller sizeof(hd->c_filesize), HEX); 66557198Smuller # endif 66657198Smuller arcn->sb.st_nlink = (nlink_t)asc_ul(hd->c_nlink, sizeof(hd->c_nlink), 66757198Smuller HEX); 66857198Smuller devmajor = (dev_t)asc_ul(hd->c_maj, sizeof(hd->c_maj), HEX); 66957198Smuller devminor = (dev_t)asc_ul(hd->c_min, sizeof(hd->c_min), HEX); 67057198Smuller arcn->sb.st_dev = TODEV(devmajor, devminor); 67157198Smuller devmajor = (dev_t)asc_ul(hd->c_rmaj, sizeof(hd->c_maj), HEX); 67257198Smuller devminor = (dev_t)asc_ul(hd->c_rmin, sizeof(hd->c_min), HEX); 67357198Smuller arcn->sb.st_rdev = TODEV(devmajor, devminor); 67457198Smuller arcn->crc = asc_ul(hd->c_chksum, sizeof(hd->c_chksum), HEX); 67557198Smuller 67657198Smuller /* 67757198Smuller * check the length of the file name, if ok read it in, return -1 if 67857198Smuller * bogus 67957198Smuller */ 68057198Smuller if ((nsz = (int)asc_ul(hd->c_namesize,sizeof(hd->c_namesize),HEX)) < 2) 68157198Smuller return(-1); 68257198Smuller arcn->nlen = nsz - 1; 68357198Smuller if (rd_nm(arcn, nsz) < 0) 68457198Smuller return(-1); 68557198Smuller 68657198Smuller /* 68757198Smuller * skip padding. header + filename is aligned to 4 byte boundries 68857198Smuller */ 68957198Smuller if (rd_skip((off_t)(VCPIO_PAD(sizeof(HD_VCPIO) + nsz))) < 0) 69057198Smuller return(-1); 69157198Smuller 69257198Smuller /* 69357198Smuller * if not a link (or a file with no data), calculate pad size (for 69457198Smuller * padding which follows the file data), clear the link name and return 69557198Smuller */ 69657198Smuller if (((arcn->sb.st_mode&C_IFMT) != C_ISLNK)||(arcn->sb.st_size == 0)) { 69757198Smuller /* 69857198Smuller * we have a valid header (not a link) 69957198Smuller */ 70057198Smuller arcn->ln_nlen = 0; 70157198Smuller arcn->ln_name[0] = '\0'; 70257198Smuller arcn->pad = VCPIO_PAD(arcn->sb.st_size); 70357198Smuller return(com_rd(arcn)); 70457198Smuller } 70557198Smuller 70657198Smuller /* 70757198Smuller * read in the link name and skip over the padding 70857198Smuller */ 70957198Smuller if ((rd_ln_nm(arcn) < 0) || 71057198Smuller (rd_skip((off_t)(VCPIO_PAD(arcn->sb.st_size))) < 0)) 71157198Smuller return(-1); 71257198Smuller 71357198Smuller /* 71457198Smuller * we have a valid header (with a link) 71557198Smuller */ 71657198Smuller return(com_rd(arcn)); 71757198Smuller } 71857198Smuller 71957198Smuller /* 72057198Smuller * vcpio_endrd() 72157198Smuller * no cleanup needed here, just return size of the trailer (for append) 72257198Smuller * Return: 72357198Smuller * size of trailer header in this format 72457198Smuller */ 72557198Smuller 72657198Smuller #if __STDC__ 72757198Smuller off_t 72857198Smuller vcpio_endrd(void) 72957198Smuller #else 73057198Smuller off_t 73157198Smuller vcpio_endrd() 73257198Smuller #endif 73357198Smuller { 73457198Smuller return((off_t)(sizeof(HD_VCPIO) + sizeof(TRAILER) + 73557198Smuller (VCPIO_PAD(sizeof(HD_VCPIO) + sizeof(TRAILER))))); 73657198Smuller } 73757198Smuller 73857198Smuller /* 73957198Smuller * crc_stwr() 74057198Smuller * start up the device mapping table, enable crc file calculation 74157198Smuller * Return: 74257198Smuller * 0 if ok, -1 otherwise (what dev_start() returns) 74357198Smuller */ 74457198Smuller 74557198Smuller #if __STDC__ 74657198Smuller int 74757198Smuller crc_stwr(void) 74857198Smuller #else 74957198Smuller int 75057198Smuller crc_stwr() 75157198Smuller #endif 75257198Smuller { 75357198Smuller docrc = 1; 75457198Smuller return(dev_start()); 75557198Smuller } 75657198Smuller 75757198Smuller /* 75857198Smuller * vcpio_wr() 75957198Smuller * copy the data in the ARCHD to buffer in system VR4 cpio 76057198Smuller * (with/without crc) format. 76157198Smuller * Return 762*57499Smuller * 0 if file has data to be written after the header, 1 if file has 763*57499Smuller * NO data to write after the header, -1 if archive write failed 76457198Smuller */ 76557198Smuller 76657198Smuller #if __STDC__ 76757198Smuller int 76857198Smuller vcpio_wr(register ARCHD *arcn) 76957198Smuller #else 77057198Smuller int 77157198Smuller vcpio_wr(arcn) 77257198Smuller register ARCHD *arcn; 77357198Smuller #endif 77457198Smuller { 77557198Smuller register HD_VCPIO *hd; 77657198Smuller unsigned int nsz; 77757198Smuller char hdblk[sizeof(HD_VCPIO)]; 77857198Smuller 77957198Smuller /* 78057198Smuller * check and repair truncated device and inode fields in the cpio 78157198Smuller * header 78257198Smuller */ 78357198Smuller if (map_dev(arcn, (u_long)VCPIO_MASK, (u_long)VCPIO_MASK) < 0) 78457198Smuller return(-1); 78557198Smuller nsz = arcn->nlen + 1; 78657198Smuller hd = (HD_VCPIO *)hdblk; 78757198Smuller if ((arcn->type != PAX_BLK) && (arcn->type != PAX_CHR)) 78857198Smuller arcn->sb.st_rdev = 0; 78957198Smuller 79057198Smuller /* 79157198Smuller * add the proper magic value depending whether we were asked for 79257198Smuller * file data crc's, and the crc if needed. 79357198Smuller */ 79457198Smuller if (docrc) { 79557198Smuller if (ul_asc((u_long)VCMAGIC, hd->c_magic, sizeof(hd->c_magic), 79657198Smuller OCT) || 79757198Smuller ul_asc((u_long)arcn->crc,hd->c_chksum,sizeof(hd->c_chksum), 79857198Smuller HEX)) 79957198Smuller goto out; 80057198Smuller } else { 80157198Smuller if (ul_asc((u_long)VMAGIC, hd->c_magic, sizeof(hd->c_magic), 80257198Smuller OCT) || 80357198Smuller ul_asc((u_long)0L, hd->c_chksum, sizeof(hd->c_chksum),HEX)) 80457198Smuller goto out; 80557198Smuller } 80657198Smuller 80757198Smuller switch(arcn->type) { 80857198Smuller case PAX_CTG: 80957198Smuller case PAX_REG: 81057198Smuller case PAX_HRG: 81157198Smuller /* 81257198Smuller * caller will copy file data to the archive. tell him how 81357198Smuller * much to pad. 81457198Smuller */ 81557198Smuller arcn->pad = VCPIO_PAD(arcn->sb.st_size); 81657198Smuller # ifdef NET2_STAT 81757198Smuller if (ul_asc((u_long)arcn->sb.st_size, hd->c_filesize, 81857198Smuller sizeof(hd->c_filesize), HEX)) { 81957198Smuller # else 82057198Smuller if (uqd_asc((u_quad_t)arcn->sb.st_size, hd->c_filesize, 82157198Smuller sizeof(hd->c_filesize), HEX)) { 82257198Smuller # endif 82357198Smuller warn(1,"File is too large for sv4cpio format %s", 82457198Smuller arcn->org_name); 82557198Smuller return(1); 82657198Smuller } 82757198Smuller break; 82857198Smuller case PAX_SLK: 82957198Smuller /* 83057198Smuller * no file data for the caller to process, the file data has 83157198Smuller * the size of the link 83257198Smuller */ 83357198Smuller arcn->pad = 0L; 83457198Smuller if (ul_asc((u_long)arcn->ln_nlen, hd->c_filesize, 83557198Smuller sizeof(hd->c_filesize), HEX)) 83657198Smuller goto out; 83757198Smuller break; 83857198Smuller default: 83957198Smuller /* 84057198Smuller * no file data for the caller to process 84157198Smuller */ 84257198Smuller arcn->pad = 0L; 84357198Smuller if (ul_asc((u_long)0L, hd->c_filesize, sizeof(hd->c_filesize), 84457198Smuller HEX)) 84557198Smuller goto out; 84657198Smuller break; 84757198Smuller } 84857198Smuller 84957198Smuller /* 85057198Smuller * set the other fields in the header 85157198Smuller */ 85257198Smuller if (ul_asc((u_long)arcn->sb.st_ino, hd->c_ino, sizeof(hd->c_ino), 85357198Smuller HEX) || 85457198Smuller ul_asc((u_long)arcn->sb.st_mode, hd->c_mode, sizeof(hd->c_mode), 85557198Smuller HEX) || 85657198Smuller ul_asc((u_long)arcn->sb.st_uid, hd->c_uid, sizeof(hd->c_uid), 85757198Smuller HEX) || 85857198Smuller ul_asc((u_long)arcn->sb.st_gid, hd->c_gid, sizeof(hd->c_gid), 85957198Smuller HEX) || 86057198Smuller ul_asc((u_long)arcn->sb.st_mtime, hd->c_mtime, sizeof(hd->c_mtime), 86157198Smuller HEX) || 86257198Smuller ul_asc((u_long)arcn->sb.st_nlink, hd->c_nlink, sizeof(hd->c_nlink), 86357198Smuller HEX) || 86457198Smuller ul_asc((u_long)MAJOR(arcn->sb.st_dev),hd->c_maj, sizeof(hd->c_maj), 86557198Smuller HEX) || 86657198Smuller ul_asc((u_long)MINOR(arcn->sb.st_dev),hd->c_min, sizeof(hd->c_min), 86757198Smuller HEX) || 86857198Smuller ul_asc((u_long)MAJOR(arcn->sb.st_rdev),hd->c_rmaj,sizeof(hd->c_maj), 86957198Smuller HEX) || 87057198Smuller ul_asc((u_long)MINOR(arcn->sb.st_rdev),hd->c_rmin,sizeof(hd->c_min), 87157198Smuller HEX) || 87257198Smuller ul_asc((u_long)nsz, hd->c_namesize, sizeof(hd->c_namesize), HEX)) 87357198Smuller goto out; 87457198Smuller 87557198Smuller /* 87657198Smuller * write the header, the file name and padding as required. 87757198Smuller */ 87857198Smuller if ((wr_rdbuf(hdblk, (int)sizeof(HD_VCPIO)) < 0) || 87957198Smuller (wr_rdbuf(arcn->name, (int)nsz) < 0) || 88057198Smuller (wr_skip((off_t)(VCPIO_PAD(sizeof(HD_VCPIO) + nsz))) < 0)) { 88157198Smuller warn(1,"Could not write sv4cpio header for %s",arcn->org_name); 88257198Smuller return(-1); 88357198Smuller } 88457198Smuller 88557198Smuller /* 88657198Smuller * if we have file data, tell the caller we are done, copy the file 88757198Smuller */ 88857198Smuller if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG) || 88957198Smuller (arcn->type == PAX_HRG)) 89057198Smuller return(0); 89157198Smuller 89257198Smuller /* 89357198Smuller * if we are not a link, tell the caller we are done, go to next file 89457198Smuller */ 89557198Smuller if (arcn->type != PAX_SLK) 89657198Smuller return(1); 89757198Smuller 89857198Smuller /* 89957198Smuller * write the link name, tell the caller we are done. 90057198Smuller */ 90157198Smuller if ((wr_rdbuf(arcn->ln_name, arcn->ln_nlen) < 0) || 90257198Smuller (wr_skip((off_t)(VCPIO_PAD(arcn->ln_nlen))) < 0)) { 90357198Smuller warn(1,"Could not write sv4cpio link name for %s", 90457198Smuller arcn->org_name); 90557198Smuller return(-1); 90657198Smuller } 90757198Smuller return(1); 90857198Smuller 90957198Smuller out: 91057198Smuller /* 91157198Smuller * header field is out of range 91257198Smuller */ 91357198Smuller warn(1,"Sv4cpio header field is too small for file %s",arcn->org_name); 91457198Smuller return(1); 91557198Smuller } 91657198Smuller 91757198Smuller /* 91857198Smuller * Routines common to the old binary header cpio 91957198Smuller */ 92057198Smuller 92157198Smuller /* 92257198Smuller * bcpio_id() 92357198Smuller * determine if a block given to us is a old binary cpio header 92457198Smuller * (with/without header byte swapping) 92557198Smuller * Return: 92657198Smuller * 0 if a valid header, -1 otherwise 92757198Smuller */ 92857198Smuller 92957198Smuller #if __STDC__ 93057198Smuller int 93157198Smuller bcpio_id(char *blk, int size) 93257198Smuller #else 93357198Smuller int 93457198Smuller bcpio_id(blk, size) 93557198Smuller char *blk; 93657198Smuller int size; 93757198Smuller #endif 93857198Smuller { 93957198Smuller if (size < sizeof(HD_BCPIO)) 94057198Smuller return(-1); 94157198Smuller 94257198Smuller /* 94357198Smuller * check both normal and byte swapped magic cookies 94457198Smuller */ 94557198Smuller if (((u_short)SHRT_EXT(blk)) == MAGIC) 94657198Smuller return(0); 94757198Smuller if (((u_short)RSHRT_EXT(blk)) == MAGIC) { 94857198Smuller if (!swp_head) 94957198Smuller ++swp_head; 95057198Smuller return(0); 95157198Smuller } 95257198Smuller return(-1); 95357198Smuller } 95457198Smuller 95557198Smuller /* 95657198Smuller * bcpio_rd() 95757198Smuller * determine if a buffer is a old binary archive entry. (it may have byte 95857198Smuller * swapped header) convert and store the values in the ARCHD parameter. 95957198Smuller * This is a very old header format and should not really be used. 96057198Smuller * Return: 96157198Smuller * 0 if a valid header, -1 otherwise. 96257198Smuller */ 96357198Smuller 96457198Smuller #if __STDC__ 96557198Smuller int 96657198Smuller bcpio_rd(register ARCHD *arcn, register char *buf) 96757198Smuller #else 96857198Smuller int 96957198Smuller bcpio_rd(arcn, buf) 97057198Smuller register ARCHD *arcn; 97157198Smuller register char *buf; 97257198Smuller #endif 97357198Smuller { 97457198Smuller register HD_BCPIO *hd; 97557198Smuller register int nsz; 97657198Smuller 97757198Smuller /* 97857198Smuller * check the header 97957198Smuller */ 98057198Smuller if (bcpio_id(buf, sizeof(HD_BCPIO)) < 0) 98157198Smuller return(-1); 98257198Smuller 98357198Smuller arcn->pad = 0L; 98457198Smuller hd = (HD_BCPIO *)buf; 98557198Smuller if (swp_head) { 98657198Smuller /* 98757198Smuller * header has swapped bytes on 16 bit boundries 98857198Smuller */ 98957198Smuller arcn->sb.st_dev = (dev_t)(RSHRT_EXT(hd->h_dev)); 99057198Smuller arcn->sb.st_ino = (ino_t)(RSHRT_EXT(hd->h_ino)); 99157198Smuller arcn->sb.st_mode = (mode_t)(RSHRT_EXT(hd->h_mode)); 99257198Smuller arcn->sb.st_uid = (uid_t)(RSHRT_EXT(hd->h_uid)); 99357198Smuller arcn->sb.st_gid = (gid_t)(RSHRT_EXT(hd->h_gid)); 99457198Smuller arcn->sb.st_nlink = (nlink_t)(RSHRT_EXT(hd->h_nlink)); 99557198Smuller arcn->sb.st_rdev = (dev_t)(RSHRT_EXT(hd->h_rdev)); 99657198Smuller arcn->sb.st_mtime = (time_t)(RSHRT_EXT(hd->h_mtime_1)); 99757198Smuller arcn->sb.st_mtime = (arcn->sb.st_mtime << 16) | 99857198Smuller ((time_t)(RSHRT_EXT(hd->h_mtime_2))); 99957198Smuller arcn->sb.st_size = (off_t)(RSHRT_EXT(hd->h_filesize_1)); 100057198Smuller arcn->sb.st_size = (arcn->sb.st_size << 16) | 100157198Smuller ((off_t)(RSHRT_EXT(hd->h_filesize_2))); 100257198Smuller nsz = (int)(RSHRT_EXT(hd->h_namesize)); 100357198Smuller } else { 100457198Smuller arcn->sb.st_dev = (dev_t)(SHRT_EXT(hd->h_dev)); 100557198Smuller arcn->sb.st_ino = (ino_t)(SHRT_EXT(hd->h_ino)); 100657198Smuller arcn->sb.st_mode = (mode_t)(SHRT_EXT(hd->h_mode)); 100757198Smuller arcn->sb.st_uid = (uid_t)(SHRT_EXT(hd->h_uid)); 100857198Smuller arcn->sb.st_gid = (gid_t)(SHRT_EXT(hd->h_gid)); 100957198Smuller arcn->sb.st_nlink = (nlink_t)(SHRT_EXT(hd->h_nlink)); 101057198Smuller arcn->sb.st_rdev = (dev_t)(SHRT_EXT(hd->h_rdev)); 101157198Smuller arcn->sb.st_mtime = (time_t)(SHRT_EXT(hd->h_mtime_1)); 101257198Smuller arcn->sb.st_mtime = (arcn->sb.st_mtime << 16) | 101357198Smuller ((time_t)(SHRT_EXT(hd->h_mtime_2))); 101457198Smuller arcn->sb.st_size = (off_t)(SHRT_EXT(hd->h_filesize_1)); 101557198Smuller arcn->sb.st_size = (arcn->sb.st_size << 16) | 101657198Smuller ((off_t)(SHRT_EXT(hd->h_filesize_2))); 101757198Smuller nsz = (int)(SHRT_EXT(hd->h_namesize)); 101857198Smuller } 1019*57499Smuller arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime; 102057198Smuller 102157198Smuller /* 102257198Smuller * check the file name size, if bogus give up. otherwise read the file 102357198Smuller * name 102457198Smuller */ 102557198Smuller if (nsz < 2) 102657198Smuller return(-1); 102757198Smuller arcn->nlen = nsz - 1; 102857198Smuller if (rd_nm(arcn, nsz) < 0) 102957198Smuller return(-1); 103057198Smuller 103157198Smuller /* 103257198Smuller * header + file name are aligned to 2 byte boundries, skip if needed 103357198Smuller */ 103457198Smuller if (rd_skip((off_t)(BCPIO_PAD(sizeof(HD_BCPIO) + nsz))) < 0) 103557198Smuller return(-1); 103657198Smuller 103757198Smuller /* 103857198Smuller * if not a link (or a file with no data), calculate pad size (for 103957198Smuller * padding which follows the file data), clear the link name and return 104057198Smuller */ 104157198Smuller if (((arcn->sb.st_mode & C_IFMT) != C_ISLNK)||(arcn->sb.st_size == 0)){ 104257198Smuller /* 104357198Smuller * we have a valid header (not a link) 104457198Smuller */ 104557198Smuller arcn->ln_nlen = 0; 104657198Smuller arcn->ln_name[0] = '\0'; 104757198Smuller arcn->pad = BCPIO_PAD(arcn->sb.st_size); 104857198Smuller return(com_rd(arcn)); 104957198Smuller } 105057198Smuller 105157198Smuller if ((rd_ln_nm(arcn) < 0) || 105257198Smuller (rd_skip((off_t)(BCPIO_PAD(arcn->sb.st_size))) < 0)) 105357198Smuller return(-1); 105457198Smuller 105557198Smuller /* 105657198Smuller * we have a valid header (with a link) 105757198Smuller */ 105857198Smuller return(com_rd(arcn)); 105957198Smuller } 106057198Smuller 106157198Smuller /* 106257198Smuller * bcpio_endrd() 106357198Smuller * no cleanup needed here, just return size of the trailer (for append) 106457198Smuller * Return: 106557198Smuller * size of trailer header in this format 106657198Smuller */ 106757198Smuller 106857198Smuller #if __STDC__ 106957198Smuller off_t 107057198Smuller bcpio_endrd(void) 107157198Smuller #else 107257198Smuller off_t 107357198Smuller bcpio_endrd() 107457198Smuller #endif 107557198Smuller { 107657198Smuller return((off_t)(sizeof(HD_BCPIO) + sizeof(TRAILER) + 107757198Smuller (BCPIO_PAD(sizeof(HD_BCPIO) + sizeof(TRAILER))))); 107857198Smuller } 107957198Smuller 108057198Smuller /* 108157198Smuller * bcpio_wr() 108257198Smuller * copy the data in the ARCHD to buffer in old binary cpio format 108357198Smuller * There is a real chance of field overflow with this critter. So we 108457198Smuller * always check the conversion is ok. nobody in his their right mind 108557198Smuller * should write an achive in this format... 108657198Smuller * Return 108757198Smuller * 0 if file has data to be written after the header, 1 if file has NO 108857198Smuller * data to write after the header, -1 if archive write failed 108957198Smuller */ 109057198Smuller 109157198Smuller #if __STDC__ 109257198Smuller int 109357198Smuller bcpio_wr(register ARCHD *arcn) 109457198Smuller #else 109557198Smuller int 109657198Smuller bcpio_wr(arcn) 109757198Smuller register ARCHD *arcn; 109857198Smuller #endif 109957198Smuller { 110057198Smuller register HD_BCPIO *hd; 110157198Smuller register int nsz; 110257198Smuller char hdblk[sizeof(HD_BCPIO)]; 110357198Smuller off_t t_offt; 110457198Smuller int t_int; 110557198Smuller time_t t_timet; 110657198Smuller 110757198Smuller /* 110857198Smuller * check and repair truncated device and inode fields in the cpio 110957198Smuller * header 111057198Smuller */ 111157198Smuller if (map_dev(arcn, (u_long)BCPIO_MASK, (u_long)BCPIO_MASK) < 0) 111257198Smuller return(-1); 111357198Smuller 111457198Smuller if ((arcn->type != PAX_BLK) && (arcn->type != PAX_CHR)) 111557198Smuller arcn->sb.st_rdev = 0; 111657198Smuller hd = (HD_BCPIO *)hdblk; 111757198Smuller 111857198Smuller switch(arcn->type) { 111957198Smuller case PAX_CTG: 112057198Smuller case PAX_REG: 112157198Smuller case PAX_HRG: 112257198Smuller /* 112357198Smuller * caller will copy file data to the archive. tell him how 112457198Smuller * much to pad. 112557198Smuller */ 112657198Smuller arcn->pad = BCPIO_PAD(arcn->sb.st_size); 112757198Smuller hd->h_filesize_1[0] = CHR_WR_0(arcn->sb.st_size); 112857198Smuller hd->h_filesize_1[1] = CHR_WR_1(arcn->sb.st_size); 112957198Smuller hd->h_filesize_2[0] = CHR_WR_2(arcn->sb.st_size); 113057198Smuller hd->h_filesize_2[1] = CHR_WR_3(arcn->sb.st_size); 113157198Smuller t_offt = (off_t)(SHRT_EXT(hd->h_filesize_1)); 113257198Smuller t_offt = (t_offt<<16) | ((off_t)(SHRT_EXT(hd->h_filesize_2))); 113357198Smuller if (arcn->sb.st_size != t_offt) { 113457198Smuller warn(1,"File is too large for bcpio format %s", 113557198Smuller arcn->org_name); 113657198Smuller return(1); 113757198Smuller } 113857198Smuller break; 113957198Smuller case PAX_SLK: 114057198Smuller /* 114157198Smuller * no file data for the caller to process, the file data has 114257198Smuller * the size of the link 114357198Smuller */ 114457198Smuller arcn->pad = 0L; 114557198Smuller hd->h_filesize_1[0] = CHR_WR_0(arcn->ln_nlen); 114657198Smuller hd->h_filesize_1[1] = CHR_WR_1(arcn->ln_nlen); 114757198Smuller hd->h_filesize_2[0] = CHR_WR_2(arcn->ln_nlen); 114857198Smuller hd->h_filesize_2[1] = CHR_WR_3(arcn->ln_nlen); 114957198Smuller t_int = (int)(SHRT_EXT(hd->h_filesize_1)); 115057198Smuller t_int = (t_int << 16) | ((int)(SHRT_EXT(hd->h_filesize_2))); 115157198Smuller if (arcn->ln_nlen != t_int) 115257198Smuller goto out; 115357198Smuller break; 115457198Smuller default: 115557198Smuller /* 115657198Smuller * no file data for the caller to process 115757198Smuller */ 115857198Smuller arcn->pad = 0L; 115957198Smuller hd->h_filesize_1[0] = (char)0; 116057198Smuller hd->h_filesize_1[1] = (char)0; 116157198Smuller hd->h_filesize_2[0] = (char)0; 116257198Smuller hd->h_filesize_2[1] = (char)0; 116357198Smuller break; 116457198Smuller } 116557198Smuller 116657198Smuller /* 116757198Smuller * build up the rest of the fields 116857198Smuller */ 116957198Smuller hd->h_magic[0] = CHR_WR_2(MAGIC); 117057198Smuller hd->h_magic[1] = CHR_WR_3(MAGIC); 117157198Smuller hd->h_dev[0] = CHR_WR_2(arcn->sb.st_dev); 117257198Smuller hd->h_dev[1] = CHR_WR_3(arcn->sb.st_dev); 117357198Smuller if (arcn->sb.st_dev != (dev_t)(SHRT_EXT(hd->h_dev))) 117457198Smuller goto out; 117557198Smuller hd->h_ino[0] = CHR_WR_2(arcn->sb.st_ino); 117657198Smuller hd->h_ino[1] = CHR_WR_3(arcn->sb.st_ino); 117757198Smuller if (arcn->sb.st_ino != (ino_t)(SHRT_EXT(hd->h_ino))) 117857198Smuller goto out; 117957198Smuller hd->h_mode[0] = CHR_WR_2(arcn->sb.st_mode); 118057198Smuller hd->h_mode[1] = CHR_WR_3(arcn->sb.st_mode); 118157198Smuller if (arcn->sb.st_mode != (mode_t)(SHRT_EXT(hd->h_mode))) 118257198Smuller goto out; 118357198Smuller hd->h_uid[0] = CHR_WR_2(arcn->sb.st_uid); 118457198Smuller hd->h_uid[1] = CHR_WR_3(arcn->sb.st_uid); 118557198Smuller if (arcn->sb.st_uid != (uid_t)(SHRT_EXT(hd->h_uid))) 118657198Smuller goto out; 118757198Smuller hd->h_gid[0] = CHR_WR_2(arcn->sb.st_gid); 118857198Smuller hd->h_gid[1] = CHR_WR_3(arcn->sb.st_gid); 118957198Smuller if (arcn->sb.st_gid != (gid_t)(SHRT_EXT(hd->h_gid))) 119057198Smuller goto out; 119157198Smuller hd->h_nlink[0] = CHR_WR_2(arcn->sb.st_nlink); 119257198Smuller hd->h_nlink[1] = CHR_WR_3(arcn->sb.st_nlink); 119357198Smuller if (arcn->sb.st_nlink != (nlink_t)(SHRT_EXT(hd->h_nlink))) 119457198Smuller goto out; 119557198Smuller hd->h_rdev[0] = CHR_WR_2(arcn->sb.st_rdev); 119657198Smuller hd->h_rdev[1] = CHR_WR_3(arcn->sb.st_rdev); 119757198Smuller if (arcn->sb.st_rdev != (dev_t)(SHRT_EXT(hd->h_rdev))) 119857198Smuller goto out; 119957198Smuller hd->h_mtime_1[0] = CHR_WR_0(arcn->sb.st_mtime); 120057198Smuller hd->h_mtime_1[1] = CHR_WR_1(arcn->sb.st_mtime); 120157198Smuller hd->h_mtime_2[0] = CHR_WR_2(arcn->sb.st_mtime); 120257198Smuller hd->h_mtime_2[1] = CHR_WR_3(arcn->sb.st_mtime); 120357198Smuller t_timet = (time_t)(SHRT_EXT(hd->h_mtime_1)); 120457198Smuller t_timet = (t_timet << 16) | ((time_t)(SHRT_EXT(hd->h_mtime_2))); 120557198Smuller if (arcn->sb.st_mtime != t_timet) 120657198Smuller goto out; 120757198Smuller nsz = arcn->nlen + 1; 120857198Smuller hd->h_namesize[0] = CHR_WR_2(nsz); 120957198Smuller hd->h_namesize[1] = CHR_WR_3(nsz); 121057198Smuller if (nsz != (int)(SHRT_EXT(hd->h_namesize))) 121157198Smuller goto out; 121257198Smuller 121357198Smuller /* 121457198Smuller * write the header, the file name and padding as required. 121557198Smuller */ 121657198Smuller if ((wr_rdbuf(hdblk, (int)sizeof(HD_BCPIO)) < 0) || 121757198Smuller (wr_rdbuf(arcn->name, nsz) < 0) || 121857198Smuller (wr_skip((off_t)(BCPIO_PAD(sizeof(HD_BCPIO) + nsz))) < 0)) { 121957198Smuller warn(1, "Could not write bcpio header for %s", arcn->org_name); 122057198Smuller return(-1); 122157198Smuller } 122257198Smuller 122357198Smuller /* 122457198Smuller * if we have file data, tell the caller we are done 122557198Smuller */ 122657198Smuller if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG) || 122757198Smuller (arcn->type == PAX_HRG)) 122857198Smuller return(0); 122957198Smuller 123057198Smuller /* 123157198Smuller * if we are not a link, tell the caller we are done, go to next file 123257198Smuller */ 123357198Smuller if (arcn->type != PAX_SLK) 123457198Smuller return(1); 123557198Smuller 123657198Smuller /* 123757198Smuller * write the link name, tell the caller we are done. 123857198Smuller */ 123957198Smuller if ((wr_rdbuf(arcn->ln_name, arcn->ln_nlen) < 0) || 124057198Smuller (wr_skip((off_t)(BCPIO_PAD(arcn->ln_nlen))) < 0)) { 124157198Smuller warn(1,"Could not write bcpio link name for %s",arcn->org_name); 124257198Smuller return(-1); 124357198Smuller } 124457198Smuller return(1); 124557198Smuller 124657198Smuller out: 124757198Smuller /* 124857198Smuller * header field is out of range 124957198Smuller */ 125057198Smuller warn(1,"Bcpio header field is too small for file %s", arcn->org_name); 125157198Smuller return(1); 125257198Smuller } 1253