⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ar_subs.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
/*- * 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[] = "@(#)ar_subs.c	8.2 (Berkeley) 4/18/94";#endif /* not lint */#include <sys/types.h>#include <sys/time.h>#include <sys/stat.h>#include <sys/param.h>#include <signal.h>#include <string.h>#include <stdio.h>#include <ctype.h>#include <fcntl.h>#include <errno.h>#include <unistd.h>#include <stdlib.h>#include "pax.h"#include "extern.h"static void wr_archive __P((register ARCHD *, int is_app));static int get_arc __P((void));static int next_head __P((register ARCHD *));extern sigset_t s_mask;/* * Routines which control the overall operation modes of pax as specified by * the user: list, append, read ... */static char hdbuf[BLKMULT];             /* space for archive header on read */u_long flcnt;				/* number of files processed *//* * list() *	list the contents of an archive which match user supplied pattern(s) *	(no pattern matches all). */#if __STDC__voidlist(void)#elsevoidlist()#endif{	register ARCHD *arcn;	register int res;	ARCHD archd;	time_t now;	arcn = &archd;	/*	 * figure out archive type; pass any format specific options to the	 * archive option processing routine; call the format init routine. We	 * also save current time for ls_list() so we do not make a system	 * call for each file we need to print. If verbose (vflag) start up	 * the name and group caches.	 */	if ((get_arc() < 0) || ((*frmt->options)() < 0) ||	    ((*frmt->st_rd)() < 0))		return;	if (vflag && ((uidtb_start() < 0) || (gidtb_start() < 0)))		return;	now = time((time_t *)NULL);	/*	 * step through the archive until the format says it is done	 */	while (next_head(arcn) == 0) {		/*		 * check for pattern, and user specified options match.		 * When all patterns are matched we are done.		 */		if ((res = pat_match(arcn)) < 0)			break;		if ((res == 0) && (sel_chk(arcn) == 0)) {			/*			 * pattern resulted in a selected file			 */			if (pat_sel(arcn) < 0)				break;			/*			 * modify the name as requested by the user if name			 * survives modification, do a listing of the file			 */			if ((res = mod_name(arcn)) < 0)				break;			if (res == 0)				ls_list(arcn, now);		}		/*		 * skip to next archive format header using values calculated		 * by the format header read routine		 */		if (rd_skip(arcn->skip + arcn->pad) == 1)			break;	}	/*	 * all done, let format have a chance to cleanup, and make sure that	 * the patterns supplied by the user were all matched	 */	(void)(*frmt->end_rd)();	(void)sigprocmask(SIG_BLOCK, &s_mask, (sigset_t *)NULL);	ar_close();	pat_chk();}/* * extract() *	extract the member(s) of an archive as specified by user supplied *	pattern(s) (no patterns extracts all members) */#if __STDC__voidextract(void)#elsevoidextract()#endif{	register ARCHD *arcn;	register int res;	off_t cnt;	ARCHD archd;	struct stat sb;	int fd;	arcn = &archd;	/*	 * figure out archive type; pass any format specific options to the	 * archive option processing routine; call the format init routine;	 * start up the directory modification time and access mode database	 */	if ((get_arc() < 0) || ((*frmt->options)() < 0) ||	    ((*frmt->st_rd)() < 0) || (dir_start() < 0))		return;	/*	 * When we are doing interactive rename, we store the mapping of names	 * so we can fix up hard links files later in the archive.	 */	if (iflag && (name_start() < 0))		return;	/*	 * step through each entry on the archive until the format read routine	 * says it is done	 */	while (next_head(arcn) == 0) {		/*		 * check for pattern, and user specified options match. When		 * all the patterns are matched we are done		 */		if ((res = pat_match(arcn)) < 0)			break;		if ((res > 0) || (sel_chk(arcn) != 0)) {			/*			 * file is not selected. skip past any file data and			 * padding and go back for the next archive member			 */			(void)rd_skip(arcn->skip + arcn->pad);			continue;		}		/*		 * with -u or -D only extract when the archive member is newer		 * than the file with the same name in the file system (nos		 * test of being the same type is required).		 * NOTE: this test is done BEFORE name modifications as		 * specified by pax. this operation can be confusing to the		 * user who might expect the test to be done on an existing		 * file AFTER the name mod. In honesty the pax spec is probably		 * flawed in this respect.		 */		if ((uflag || Dflag) && ((lstat(arcn->name, &sb) == 0))) {			if (uflag && Dflag) {				if ((arcn->sb.st_mtime <= sb.st_mtime) &&				    (arcn->sb.st_ctime <= sb.st_ctime)) {					(void)rd_skip(arcn->skip + arcn->pad);					continue;				}			} else if (Dflag) {				if (arcn->sb.st_ctime <= sb.st_ctime) {					(void)rd_skip(arcn->skip + arcn->pad);					continue;				}			} else if (arcn->sb.st_mtime <= sb.st_mtime) {				(void)rd_skip(arcn->skip + arcn->pad);				continue;			}		}		/*		 * this archive member is now been selected. modify the name.		 */		if ((pat_sel(arcn) < 0) || ((res = mod_name(arcn)) < 0))			break;		if (res > 0) {			/*			 * a bad name mod, skip and purge name from link table			 */			purg_lnk(arcn);			(void)rd_skip(arcn->skip + arcn->pad);			continue;		}		/*		 * Non standard -Y and -Z flag. When the exisiting file is		 * same age or newer skip		 */		if ((Yflag || Zflag) && ((lstat(arcn->name, &sb) == 0))) {			if (Yflag && Zflag) {				if ((arcn->sb.st_mtime <= sb.st_mtime) &&				    (arcn->sb.st_ctime <= sb.st_ctime)) {					(void)rd_skip(arcn->skip + arcn->pad);					continue;				}			} else if (Yflag) {				if (arcn->sb.st_ctime <= sb.st_ctime) {					(void)rd_skip(arcn->skip + arcn->pad);					continue;				}			} else if (arcn->sb.st_mtime <= sb.st_mtime) {				(void)rd_skip(arcn->skip + arcn->pad);				continue;			}		}		if (vflag) {			(void)fputs(arcn->name, stderr);			vfpart = 1;		}		/*		 * all ok, extract this member based on type		 */		if ((arcn->type != PAX_REG) && (arcn->type != PAX_CTG)) {			/*			 * process archive members that are not regular files.			 * throw out padding and any data that might follow the			 * header (as determined by the format).			 */			if ((arcn->type == PAX_HLK) || (arcn->type == PAX_HRG))				res = lnk_creat(arcn);			else				res = node_creat(arcn);			(void)rd_skip(arcn->skip + arcn->pad);			if (res < 0)				purg_lnk(arcn);			if (vflag && vfpart) {				(void)putc('\n', stderr);				vfpart = 0;			}			continue;		}		/*		 * we have a file with data here. If we can not create it, skip		 * over the data and purge the name from hard link table		 */		if ((fd = file_creat(arcn)) < 0) {			(void)rd_skip(arcn->skip + arcn->pad);			purg_lnk(arcn);			continue;		}		/*		 * extract the file from the archive and skip over padding and		 * any unprocessed data		 */		res = (*frmt->rd_data)(arcn, fd, &cnt);		file_close(arcn, fd);		if (vflag && vfpart) {			(void)putc('\n', stderr);			vfpart = 0;		}		if (!res)			(void)rd_skip(cnt + arcn->pad);	}	/*	 * all done, restore directory modes and times as required; make sure	 * all patterns supplied by the user were matched; block off signals	 * to avoid chance for multiple entry into the cleanup code.	 */	(void)(*frmt->end_rd)();	(void)sigprocmask(SIG_BLOCK, &s_mask, (sigset_t *)NULL);	ar_close();	proc_dir();	pat_chk();}/* * wr_archive() *	Write an archive. used in both creating a new archive and appends on *	previously written archive. */#if __STDC__static voidwr_archive(register ARCHD *arcn, int is_app)#elsestatic voidwr_archive(arcn, is_app)	register ARCHD *arcn;	int is_app;#endif{	register int res;	register int hlk;	register int wr_one;	off_t cnt;	int (*wrf)();	int fd = -1;	/*	 * if this format supports hard link storage, start up the database	 * that detects them.	 */	if (((hlk = frmt->hlk) == 1) && (lnk_start() < 0))		return;	/*	 * start up the file traversal code and format specific write	 */	if ((ftree_start() < 0) || ((*frmt->st_wr)() < 0))		return;	wrf = frmt->wr;	/*	 * When we are doing interactive rename, we store the mapping of names	 * so we can fix up hard links files later in the archive.	 */	if (iflag && (name_start() < 0))		return;	/*	 * if this not append, and there are no files, we do no write a trailer	 */	wr_one = is_app;	/*	 * while there are files to archive, process them one at at time	 */	while (next_file(arcn) == 0) {		/*		 * check if this file meets user specified options match.		 */		if (sel_chk(arcn) != 0)			continue;		fd = -1;		if (uflag) {			/*			 * only archive if this file is newer than a file with			 * the same name that is already stored on the archive			 */			if ((res = chk_ftime(arcn)) < 0)				break;			if (res > 0)				continue;		}		/*		 * this file is considered selected now. see if this is a hard		 * link to a file already stored		 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -