📄 cpio.c
字号:
/*- * Copyright (c) 1992 Keith Muller. * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Keith Muller of the University of California, San Diego. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char sccsid[] = "@(#)cpio.c 8.1 (Berkeley) 5/31/93";#endif /* not lint */#include <sys/types.h>#include <sys/time.h>#include <sys/stat.h>#include <sys/param.h>#include <string.h>#include <ctype.h>#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include "pax.h"#include "cpio.h"#include "extern.h"static int rd_nm __P((register ARCHD *, int));static int rd_ln_nm __P((register ARCHD *));static int com_rd __P((register ARCHD *));/* * Routines which support the different cpio versions */static int swp_head; /* binary cpio header byte swap *//* * Routines common to all versions of cpio *//* * cpio_strd() * Fire up the hard link detection code * Return: * 0 if ok -1 otherwise (the return values of lnk_start()) */#if __STDC__intcpio_strd(void)#elseintcpio_strd()#endif{ return(lnk_start());}/* * cpio_trail() * Called to determine if a header block is a valid trailer. We are * passed the block, the in_sync flag (which tells us we are in resync * mode; looking for a valid header), and cnt (which starts at zero) * which is used to count the number of empty blocks we have seen so far. * Return: * 0 if a valid trailer, -1 if not a valid trailer, */#if __STDC__intcpio_trail(register ARCHD *arcn)#elseintcpio_trail(arcn) register ARCHD *arcn;#endif{ /* * look for trailer id in file we are about to process */ if ((strcmp(arcn->name, TRAILER) == 0) && (arcn->sb.st_size == 0)) return(0); return(-1);}/* * com_rd() * operations common to all cpio read functions. * Return: * 0 */#if __STDC__static intcom_rd(register ARCHD *arcn)#elsestatic intcom_rd(arcn) register ARCHD *arcn;#endif{ arcn->skip = 0; arcn->pat = NULL; arcn->org_name = arcn->name; switch(arcn->sb.st_mode & C_IFMT) { case C_ISFIFO: arcn->type = PAX_FIF; break; case C_ISDIR: arcn->type = PAX_DIR; break; case C_ISBLK: arcn->type = PAX_BLK; break; case C_ISCHR: arcn->type = PAX_CHR; break; case C_ISLNK: arcn->type = PAX_SLK; break; case C_ISOCK: arcn->type = PAX_SCK; break; case C_ISCTG: case C_ISREG: default: /* * we have file data, set up skip (pad is set in the format * specific sections) */ arcn->sb.st_mode = (arcn->sb.st_mode & 0xfff) | C_ISREG; arcn->type = PAX_REG; arcn->skip = arcn->sb.st_size; break; } if (chk_lnk(arcn) < 0) return(-1); return(0);}/* * cpio_end_wr() * write the special file with the name trailer in the proper format * Return: * result of the write of the trailer from the cpio specific write func */#if __STDC__intcpio_endwr(void)#elseintcpio_endwr()#endif{ ARCHD last; /* * create a trailer request and call the proper format write function */ bzero((char *)&last, sizeof(last)); last.nlen = sizeof(TRAILER) - 1; last.type = PAX_REG; last.sb.st_nlink = 1; (void)strcpy(last.name, TRAILER); return((*frmt->wr)(&last));}/* * rd_nam() * read in the file name which follows the cpio header * Return: * 0 if ok, -1 otherwise */#if __STDC__static intrd_nm(register ARCHD *arcn, int nsz)#elsestatic intrd_nm(arcn, nsz) register ARCHD *arcn; int nsz;#endif{ /* * do not even try bogus values */ if ((nsz == 0) || (nsz > sizeof(arcn->name))) { warn(1, "Cpio file name length %d is out of range", nsz); return(-1); } /* * read the name and make sure it is not empty and is \0 terminated */ if ((rd_wrbuf(arcn->name,nsz) != nsz) || (arcn->name[nsz-1] != '\0') || (arcn->name[0] == '\0')) { warn(1, "Cpio file name in header is corrupted"); return(-1); } return(0);}/* * rd_ln_nm() * read in the link name for a file with links. The link name is stored * like file data (and is NOT \0 terminated!) * Return: * 0 if ok, -1 otherwise */#if __STDC__static intrd_ln_nm(register ARCHD *arcn)#elsestatic intrd_ln_nm(arcn) register ARCHD *arcn;#endif{ /* * check the length specified for bogus values */ if ((arcn->sb.st_size == 0) || (arcn->sb.st_size >= sizeof(arcn->ln_name))) {# ifdef NET2_STAT warn(1, "Cpio link name length is invalid: %lu", arcn->sb.st_size);# else warn(1, "Cpio link name length is invalid: %qu", arcn->sb.st_size);# endif return(-1); } /* * read in the link name and \0 terminate it */ if (rd_wrbuf(arcn->ln_name, (int)arcn->sb.st_size) != (int)arcn->sb.st_size) { warn(1, "Cpio link name read error"); return(-1); } arcn->ln_nlen = arcn->sb.st_size; arcn->ln_name[arcn->ln_nlen] = '\0'; /* * watch out for those empty link names */ if (arcn->ln_name[0] == '\0') { warn(1, "Cpio link name is corrupt"); return(-1); } return(0);}/* * Routines common to the extended byte oriented cpio format *//* * cpio_id() * determine if a block given to us is a valid extended byte oriented * cpio header * Return: * 0 if a valid header, -1 otherwise */#if __STDC__intcpio_id(char *blk, int size)#elseintcpio_id(blk, size) char *blk; int size;#endif{ if ((size < sizeof(HD_CPIO)) || (strncmp(blk, AMAGIC, sizeof(AMAGIC) - 1) != 0)) return(-1); return(0);}/* * cpio_rd() * determine if a buffer is a byte oriented extended cpio archive entry. * convert and store the values in the ARCHD parameter. * Return: * 0 if a valid header, -1 otherwise. */#if __STDC__intcpio_rd(register ARCHD *arcn, register char *buf)#elseintcpio_rd(arcn, buf) register ARCHD *arcn; register char *buf;#endif{ register int nsz; register HD_CPIO *hd; /* * check that this is a valid header, if not return -1 */ if (cpio_id(buf, sizeof(HD_CPIO)) < 0) return(-1); hd = (HD_CPIO *)buf; /* * byte oriented cpio (posix) does not have padding! extract the octal * ascii fields from the header */ arcn->pad = 0L; arcn->sb.st_dev = (dev_t)asc_ul(hd->c_dev, sizeof(hd->c_dev), OCT); arcn->sb.st_ino = (ino_t)asc_ul(hd->c_ino, sizeof(hd->c_ino), OCT); arcn->sb.st_mode = (mode_t)asc_ul(hd->c_mode, sizeof(hd->c_mode), OCT); arcn->sb.st_uid = (uid_t)asc_ul(hd->c_uid, sizeof(hd->c_uid), OCT); arcn->sb.st_gid = (gid_t)asc_ul(hd->c_gid, sizeof(hd->c_gid), OCT); arcn->sb.st_nlink = (nlink_t)asc_ul(hd->c_nlink, sizeof(hd->c_nlink), OCT); arcn->sb.st_rdev = (dev_t)asc_ul(hd->c_rdev, sizeof(hd->c_rdev), OCT); arcn->sb.st_mtime = (time_t)asc_ul(hd->c_mtime, sizeof(hd->c_mtime), OCT); arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime;# ifdef NET2_STAT arcn->sb.st_size = (off_t)asc_ul(hd->c_filesize,sizeof(hd->c_filesize), OCT);# else arcn->sb.st_size = (off_t)asc_uqd(hd->c_filesize,sizeof(hd->c_filesize), OCT);# endif /* * check name size and if valid, read in the name of this entry (name * follows header in the archive) */ if ((nsz = (int)asc_ul(hd->c_namesize,sizeof(hd->c_namesize),OCT)) < 2) return(-1); arcn->nlen = nsz - 1; if (rd_nm(arcn, nsz) < 0) return(-1); if (((arcn->sb.st_mode&C_IFMT) != C_ISLNK)||(arcn->sb.st_size == 0)) { /* * no link name to read for this file */ arcn->ln_nlen = 0; arcn->ln_name[0] = '\0'; return(com_rd(arcn)); } /* * check link name size and read in the link name. Link names are * stored like file data. */ if (rd_ln_nm(arcn) < 0) return(-1); /* * we have a valid header (with a link) */ return(com_rd(arcn));}/* * cpio_endrd() * no cleanup needed here, just return size of the trailer (for append) * Return: * size of trailer header in this format */#if __STDC__off_tcpio_endrd(void)#elseoff_tcpio_endrd()#endif{ return((off_t)(sizeof(HD_CPIO) + sizeof(TRAILER)));}/* * cpio_stwr() * start up the device mapping table * Return: * 0 if ok, -1 otherwise (what dev_start() returns) */#if __STDC__intcpio_stwr(void)#elseint
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -