int vcpio_wr(ARCHD *arcn) { HD_VCPIO *hd; unsigned int nsz; HD_VCPIO hdblk; /* * check and repair truncated device and inode fields in the cpio * header */ if (map_dev(arcn, (u_long)VCPIO_MASK, (u_long)VCPIO_MASK) < 0) return(-1); nsz = arcn->nlen + 1; hd = &hdblk; if ((arcn->type != PAX_BLK) && (arcn->type != PAX_CHR)) arcn->sb.st_rdev = 0; /* * add the proper magic value depending whether we were asked for * file data crc's, and the crc if needed. */ if (docrc) { if (ul_asc((u_long)VCMAGIC, hd->c_magic, sizeof(hd->c_magic), OCT) || ul_asc((u_long)arcn->crc,hd->c_chksum,sizeof(hd->c_chksum), HEX)) goto out; } else { if (ul_asc((u_long)VMAGIC, hd->c_magic, sizeof(hd->c_magic), OCT) || ul_asc((u_long)0L, hd->c_chksum, sizeof(hd->c_chksum),HEX)) goto out; } switch(arcn->type) { case PAX_CTG: case PAX_REG: case PAX_HRG: /* * caller will copy file data to the archive. tell him how * much to pad. */ arcn->pad = VCPIO_PAD(arcn->sb.st_size); # ifdef NET2_STAT if (ul_asc((u_long)arcn->sb.st_size, hd->c_filesize, sizeof(hd->c_filesize), HEX)) { # else if (uqd_asc((u_quad_t)arcn->sb.st_size, hd->c_filesize, sizeof(hd->c_filesize), HEX)) { # endif paxwarn(1,"File is too large for sv4cpio format %s", arcn->org_name); return(1); } break; case PAX_SLK: /* * no file data for the caller to process, the file data has * the size of the link */ arcn->pad = 0L; if (ul_asc((u_long)arcn->ln_nlen, hd->c_filesize, sizeof(hd->c_filesize), HEX)) goto out; break; default: /* * no file data for the caller to process */ arcn->pad = 0L; if (ul_asc((u_long)0L, hd->c_filesize, sizeof(hd->c_filesize), HEX)) goto out; break; } /* * set the other fields in the header */ if (ul_asc((u_long)arcn->sb.st_ino, hd->c_ino, sizeof(hd->c_ino), HEX) || ul_asc((u_long)arcn->sb.st_mode, hd->c_mode, sizeof(hd->c_mode), HEX) || ul_asc((u_long)arcn->sb.st_uid, hd->c_uid, sizeof(hd->c_uid), HEX) || ul_asc((u_long)arcn->sb.st_gid, hd->c_gid, sizeof(hd->c_gid), HEX) || ul_asc((u_long)arcn->sb.st_mtime, hd->c_mtime, sizeof(hd->c_mtime), HEX) || ul_asc((u_long)arcn->sb.st_nlink, hd->c_nlink, sizeof(hd->c_nlink), HEX) || ul_asc((u_long)MAJOR(arcn->sb.st_dev),hd->c_maj, sizeof(hd->c_maj), HEX) || ul_asc((u_long)MINOR(arcn->sb.st_dev),hd->c_min, sizeof(hd->c_min), HEX) || ul_asc((u_long)MAJOR(arcn->sb.st_rdev),hd->c_rmaj,sizeof(hd->c_maj), HEX) || ul_asc((u_long)MINOR(arcn->sb.st_rdev),hd->c_rmin,sizeof(hd->c_min), HEX) || ul_asc((u_long)nsz, hd->c_namesize, sizeof(hd->c_namesize), HEX)) goto out; /* * write the header, the file name and padding as required. */ if ((wr_rdbuf((char *)&hdblk, (int)sizeof(HD_VCPIO)) < 0) || (wr_rdbuf(arcn->name, (int)nsz) < 0) || (wr_skip((off_t)(VCPIO_PAD(sizeof(HD_VCPIO) + nsz))) < 0)) { paxwarn(1,"Could not write sv4cpio header for %s",arcn->org_name); return(-1); } /* * if we have file data, tell the caller we are done, copy the file */ if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG) || (arcn->type == PAX_HRG)) return(0); /* * if we are not a link, tell the caller we are done, go to next file */ if (arcn->type != PAX_SLK) return(1); /* * write the link name, tell the caller we are done. */ if ((wr_rdbuf(arcn->ln_name, arcn->ln_nlen) < 0) || (wr_skip((off_t)(VCPIO_PAD(arcn->ln_nlen))) < 0)) { paxwarn(1,"Could not write sv4cpio link name for %s", arcn->org_name); return(-1); } return(1); out: /* * header field is out of range */ paxwarn(1,"Sv4cpio header field is too small for file %s",arcn->org_name); return(1); } /* * Routines common to the old binary header cpio */ /* * bcpio_id() * determine if a block given to us is an old binary cpio header * (with/without header byte swapping) * Return: * 0 if a valid header, -1 otherwise */ int bcpio_id(char *blk, int size) { if (size < (int)sizeof(HD_BCPIO)) return(-1); /* * check both normal and byte swapped magic cookies */ if (((u_short)SHRT_EXT(blk)) == MAGIC) return(0); if (((u_short)RSHRT_EXT(blk)) == MAGIC) { if (!swp_head) ++swp_head; return(0); } return(-1); } /* * bcpio_rd() * determine if a buffer is an old binary archive entry. (It may have byte * swapped header) convert and store the values in the ARCHD parameter. * This is a very old header format and should not really be used. * Return: * 0 if a valid header, -1 otherwise. */ int bcpio_rd(ARCHD *arcn, char *buf) { HD_BCPIO *hd; int nsz; /* * check the header */ if (bcpio_id(buf, sizeof(HD_BCPIO)) < 0) return(-1); arcn->pad = 0L; hd = (HD_BCPIO *)buf; if (swp_head) { /* * header has swapped bytes on 16 bit boundaries */ arcn->sb.st_dev = (dev_t)(RSHRT_EXT(hd->h_dev)); arcn->sb.st_ino = (ino_t)(RSHRT_EXT(hd->h_ino)); arcn->sb.st_mode = (mode_t)(RSHRT_EXT(hd->h_mode)); arcn->sb.st_uid = (uid_t)(RSHRT_EXT(hd->h_uid)); arcn->sb.st_gid = (gid_t)(RSHRT_EXT(hd->h_gid)); arcn->sb.st_nlink = (nlink_t)(RSHRT_EXT(hd->h_nlink)); arcn->sb.st_rdev = (dev_t)(RSHRT_EXT(hd->h_rdev)); arcn->sb.st_mtime = (time_t)(RSHRT_EXT(hd->h_mtime_1)); arcn->sb.st_mtime = (arcn->sb.st_mtime << 16) | ((time_t)(RSHRT_EXT(hd->h_mtime_2))); arcn->sb.st_size = (off_t)(RSHRT_EXT(hd->h_filesize_1)); arcn->sb.st_size = (arcn->sb.st_size << 16) | ((off_t)(RSHRT_EXT(hd->h_filesize_2))); nsz = (int)(RSHRT_EXT(hd->h_namesize)); } else { arcn->sb.st_dev = (dev_t)(SHRT_EXT(hd->h_dev)); arcn->sb.st_ino = (ino_t)(SHRT_EXT(hd->h_ino)); arcn->sb.st_mode = (mode_t)(SHRT_EXT(hd->h_mode)); arcn->sb.st_uid = (uid_t)(SHRT_EXT(hd->h_uid)); arcn->sb.st_gid = (gid_t)(SHRT_EXT(hd->h_gid)); arcn->sb.st_nlink = (nlink_t)(SHRT_EXT(hd->h_nlink)); arcn->sb.st_rdev = (dev_t)(SHRT_EXT(hd->h_rdev)); arcn->sb.st_mtime = (time_t)(SHRT_EXT(hd->h_mtime_1)); arcn->sb.st_mtime = (arcn->sb.st_mtime << 16) | ((time_t)(SHRT_EXT(hd->h_mtime_2))); arcn->sb.st_size = (off_t)(SHRT_EXT(hd->h_filesize_1)); arcn->sb.st_size = (arcn->sb.st_size << 16) | ((off_t)(SHRT_EXT(hd->h_filesize_2))); nsz = (int)(SHRT_EXT(hd->h_namesize)); } arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime; /* * check the file name size, if bogus give up. otherwise read the file * name */ if (nsz < 2) return(-1); arcn->nlen = nsz - 1; if (rd_nm(arcn, nsz) < 0) return(-1); /* * header + file name are aligned to 2 byte boundaries, skip if needed */ if (rd_skip((off_t)(BCPIO_PAD(sizeof(HD_BCPIO) + nsz))) < 0) return(-1); /* * if not a link (or a file with no data), calculate pad size (for * padding which follows the file data), clear the link name and return */ if (((arcn->sb.st_mode & C_IFMT) != C_ISLNK)||(arcn->sb.st_size == 0)){ /* * we have a valid header (not a link) */ arcn->ln_nlen = 0; arcn->ln_name[0] = '\0'; arcn->pad = BCPIO_PAD(arcn->sb.st_size); return(com_rd(arcn)); } if ((rd_ln_nm(arcn) < 0) || (rd_skip((off_t)(BCPIO_PAD(arcn->sb.st_size))) < 0)) return(-1); /* * we have a valid header (with a link) */ return(com_rd(arcn)); }
int bcpio_rd(ARCHD *arcn, char *buf) { HD_BCPIO *hd; int nsz; /* * check the header */ if (bcpio_id(buf, sizeof(HD_BCPIO)) < 0) return(-1); arcn->pad = 0L; hd = (HD_BCPIO *)buf; if (swp_head) { /* * header has swapped bytes on 16 bit boundaries */ arcn->sb.st_dev = (dev_t)(RSHRT_EXT(hd->h_dev)); arcn->sb.st_ino = (ino_t)(RSHRT_EXT(hd->h_ino)); arcn->sb.st_mode = (mode_t)(RSHRT_EXT(hd->h_mode)); arcn->sb.st_uid = (uid_t)(RSHRT_EXT(hd->h_uid)); arcn->sb.st_gid = (gid_t)(RSHRT_EXT(hd->h_gid)); arcn->sb.st_nlink = (nlink_t)(RSHRT_EXT(hd->h_nlink)); arcn->sb.st_rdev = (dev_t)(RSHRT_EXT(hd->h_rdev)); arcn->sb.st_mtime = (time_t)(RSHRT_EXT(hd->h_mtime_1)); arcn->sb.st_mtime = (arcn->sb.st_mtime << 16) | ((time_t)(RSHRT_EXT(hd->h_mtime_2))); arcn->sb.st_size = (off_t)(RSHRT_EXT(hd->h_filesize_1)); arcn->sb.st_size = (arcn->sb.st_size << 16) | ((off_t)(RSHRT_EXT(hd->h_filesize_2))); nsz = (int)(RSHRT_EXT(hd->h_namesize)); } else { arcn->sb.st_dev = (dev_t)(SHRT_EXT(hd->h_dev)); arcn->sb.st_ino = (ino_t)(SHRT_EXT(hd->h_ino)); arcn->sb.st_mode = (mode_t)(SHRT_EXT(hd->h_mode)); arcn->sb.st_uid = (uid_t)(SHRT_EXT(hd->h_uid)); arcn->sb.st_gid = (gid_t)(SHRT_EXT(hd->h_gid)); arcn->sb.st_nlink = (nlink_t)(SHRT_EXT(hd->h_nlink)); arcn->sb.st_rdev = (dev_t)(SHRT_EXT(hd->h_rdev)); arcn->sb.st_mtime = (time_t)(SHRT_EXT(hd->h_mtime_1)); arcn->sb.st_mtime = (arcn->sb.st_mtime << 16) | ((time_t)(SHRT_EXT(hd->h_mtime_2))); arcn->sb.st_size = (off_t)(SHRT_EXT(hd->h_filesize_1)); arcn->sb.st_size = (arcn->sb.st_size << 16) | ((off_t)(SHRT_EXT(hd->h_filesize_2))); nsz = (int)(SHRT_EXT(hd->h_namesize)); } arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime; /* * check the file name size, if bogus give up. otherwise read the file * name */ if (nsz < 2) return(-1); arcn->nlen = nsz - 1; if (rd_nm(arcn, nsz) < 0) return(-1); /* * header + file name are aligned to 2 byte boundaries, skip if needed */ if (rd_skip((off_t)(BCPIO_PAD(sizeof(HD_BCPIO) + nsz))) < 0) return(-1); /* * if not a link (or a file with no data), calculate pad size (for * padding which follows the file data), clear the link name and return */ if (((arcn->sb.st_mode & C_IFMT) != C_ISLNK)||(arcn->sb.st_size == 0)){ /* * we have a valid header (not a link) */ arcn->ln_nlen = 0; arcn->ln_name[0] = '\0'; arcn->pad = BCPIO_PAD(arcn->sb.st_size); return(com_rd(arcn)); } if ((rd_ln_nm(arcn) < 0) || (rd_skip((off_t)(BCPIO_PAD(arcn->sb.st_size))) < 0)) return(-1); /* * we have a valid header (with a link) */ return(com_rd(arcn)); }