ar.c

来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 916 行 · 第 1/2 页

C
916
字号
#ifndef lintstatic	char *sccsid = "@(#)ar.c	4.1	(ULTRIX)	7/17/90";#endif/* * ar - portable (ascii) format version */#include <sys/types.h>#include <sys/stat.h>#include <sys/time.h>#include <sys/param.h>#include <stdio.h>#include <ar.h>#include <signal.h>/************************************************************************ *									* *			Copyright (c) 1985,1986,1987,1988,1989 by	* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any  other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   This software is  derived  from  software  received  from  the	* *   University    of   California,   Berkeley,   and   from   Bell	* *   Laboratories.  Use, duplication, or disclosure is  subject  to	* *   restrictions  under  license  agreements  with  University  of	* *   California and with AT&T.						* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or  reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************//************************************************************************ * *			Modification History * *	Tim Newhouse, 11-April-1989 * 007- Added calls to tempnam() when not using the 'l' option so that *	the temp files will use the TMPDIR environment symbol if it is *	defined. * *	Tim Newhouse, 12-Jan-1989 * 006- Cloned match/trim routines for the -r option (rcmd) *	because it was not getting the file name truncation correct *	during the replace operation.  Pretty much a duplicate of the *	trim() and match() routines were used in a new routine rcmd_match *	which is now used just by rcmd() to do the matching of file names *	and still preserve the filename for later use in the opening of the *	file. * *	Mark Parenti, 08-Jun-1988 * 005- Changed signal handlers to void. * *	Teoman Topcubasi, 15-Jan-1988 * 004- Added a '-' in front of the options. * *	David L Ballenger, 16-Apr-1985 * 003-	Change definition of tmpnam variable to tmpname so that it doesn't *	conflict with definition of tmpnam() in <stdio.h>. * *	Stephen Reilly, 15-Feb-84 * 002- The uid and gid are unsigned elements but are being store into *	the ar files as signed elements * *	Stephen Reilly, 10-Nov-83: * 001- The n switch was not documented and is not used * ***********************************************************************/struct	stat	stbuf;struct	ar_hdr	arbuf;struct	lar_hdr {	char	lar_name[16];	long	lar_date;	u_short	lar_uid;	u_short	lar_gid;	u_short	lar_mode;	long	lar_size;} larbuf;#define	SKIP	1#define	IODD	2#define	OODD	4#define	HEAD	8char	*man	=	{ "-mrxtdpq" };		/*  004 */char	*opt	=	{ "uvbailo" };		/* slr001 n was removed */int	signum[] = {SIGHUP, SIGINT, SIGQUIT, 0};void	sigdone();long	lseek();int	rcmd();int	dcmd();int	xcmd();int	tcmd();int	pcmd();int	mcmd();int	qcmd();int	(*comfun)();char	flg[26];char	**namv;int	namc;char	*arnam;char	*ponam;char	*tdir		=	{ "/tmp" };char	*tmpname	=	{ "vXXXXX" };char	*tmp1name	=	{ "v1XXXXX" };char	*tmp2name	=	{ "v2XXXXX" };char	*tfname;char	*tf1name;char	*tf2name;char	*file;char	name[16];int	af;int	tf;int	tf1;int	tf2;int	qf;int	bastate;char	buf[MAXBSIZE];int	truncate;			/* ok to truncate argument filenames */char	*trim();char	*mktemp();char	*ctime();char	*tempnam();main(argc, argv)char *argv[];{	register i;	register char *cp;	for(i=0; signum[i]; i++)		if(signal(signum[i], SIG_IGN) != SIG_IGN)			signal(signum[i], sigdone);	if(argc < 3)		usage();	cp = argv[1];	if (*cp == '-')			/* 004 */		cp++;			/* 004 */	for(; *cp; cp++)		/* 004 */	switch(*cp) {	case 'o':	case 'l':	case 'v':	case 'u':/*	case 'n':				slr001 n not longer used */	case 'a':	case 'b':	case 'c':	case 'i':		flg[*cp - 'a']++;		continue;	case 'r':		setcom(rcmd);		continue;	case 'd':		setcom(dcmd);		continue;	case 'x':		setcom(xcmd);		continue;	case 't':		setcom(tcmd);		continue;	case 'p':		setcom(pcmd);		continue;	case 'm':		setcom(mcmd);		continue;	case 'q':		setcom(qcmd);		continue;	default:		fprintf(stderr, "ar: bad option `%c'\n", *cp);		done(1);	}	if(flg['l'-'a'] == 0) {		tmpname = "v";		tmp1name = "v1";		tmp2name = "v2";	}	if(flg['i'-'a'])		flg['b'-'a']++;	if(flg['a'-'a'] || flg['b'-'a']) {		bastate = 1;		ponam = trim(argv[2]);		argv++;		argc--;		if(argc < 3)			usage();	}	arnam = argv[2];	namv = argv+3;	namc = argc-3;	if(comfun == 0) {		if(flg['u'-'a'] == 0) {			fprintf(stderr, "ar: one of [%s] must be specified\n", man);			done(1);		}		setcom(rcmd);	}	(*comfun)();	done(notfound());}setcom(fun)int (*fun)();{	if(comfun != 0) {		fprintf(stderr, "ar: only one of [%s] allowed\n", man);		done(1);	}	comfun = fun;}rcmd(){	register f;	init();	getaf();	/* turn on trim()'s truncation to 15 chars - we need this when	 * movefil() calls trim to get the filename to store in the	 * archive file.	*/	truncate++;	while(!getdir()) {		bamatch();		if(namc == 0 || rcmd_match()) {			f = stats();			if(f < 0) {				if(namc)					fprintf(stderr, "ar: cannot open %s\n", file);				goto cp;			}			if(flg['u'-'a'])				if(stbuf.st_mtime <= larbuf.lar_date) {					close(f);					goto cp;				}			mesg('r');			copyfil(af, -1, IODD+SKIP);			movefil(f);			continue;		}	cp:		mesg('c');		copyfil(af, tf, IODD+OODD+HEAD);	}	/* turn off (reset) trim()'s job of truncation to 15 chars */	truncate--;	cleanup();}dcmd(){	init();	if(getaf())		noar();	while(!getdir()) {		if(match()) {			mesg('d');			copyfil(af, -1, IODD+SKIP);			continue;		}		mesg('c');		copyfil(af, tf, IODD+OODD+HEAD);	}	install();}xcmd(){	register f;	struct timeval tv[2];	if(getaf())		noar();	while(!getdir()) {		if(namc == 0 || match()) {			f = creat(file, larbuf.lar_mode & 0777);			if(f < 0) {				fprintf(stderr, "ar: %s cannot create\n", file);				goto sk;			}			mesg('x');			copyfil(af, f, IODD);			close(f);			if (flg['o'-'a']) {				tv[0].tv_sec = tv[1].tv_sec = larbuf.lar_date;				tv[0].tv_usec = tv[1].tv_usec = 0;				utimes(file, tv);			}			continue;		}	sk:		mesg('c');		copyfil(af, -1, IODD+SKIP);		if (namc > 0  &&  !morefil())			done(0);	}}pcmd(){	if(getaf())		noar();	while(!getdir()) {		if(namc == 0 || match()) {			if(flg['v'-'a']) {				printf("\n<%s>\n\n", file);				fflush(stdout);			}			copyfil(af, 1, IODD);			continue;		}		copyfil(af, -1, IODD+SKIP);	}}mcmd(){	init();	if(getaf())		noar();	if(flg['l' - 'a'])	    tf2name = mktemp(tmp2name);	else	    tf2name = tempnam(tdir,tmp2name);	close(creat(tf2name, 0600));	tf2 = open(tf2name, 2);	if(tf2 < 0) {		fprintf(stderr, "ar: cannot create third temp\n");		done(1);	}	while(!getdir()) {		bamatch();		if(match()) {			mesg('m');			copyfil(af, tf2, IODD+OODD+HEAD);			continue;		}		mesg('c');		copyfil(af, tf, IODD+OODD+HEAD);	}	install();}tcmd(){	if(getaf())		noar();	while(!getdir()) {		if(namc == 0 || match()) {			if(flg['v'-'a'])				longt();			printf("%s\n", trim(file));		}		copyfil(af, -1, IODD+SKIP);	}}qcmd(){	register i, f;	if (flg['a'-'a'] || flg['b'-'a']) {		fprintf(stderr, "ar: abi not allowed with q\n");		done(1);	}	truncate++;	getqf();	for(i=0; signum[i]; i++)		signal(signum[i], SIG_IGN);	lseek(qf, 0l, 2);	for(i=0; i<namc; i++) {		file = namv[i];		if(file == 0)			continue;		namv[i] = 0;		mesg('q');		f = stats();		if(f < 0) {			fprintf(stderr, "ar: %s cannot open\n", file);			continue;		}		tf = qf;		movefil(f);		qf = tf;	}}init(){	if(flg['l'-'a'])	    tfname = mktemp(tmpname);	else	    tfname = tempnam(tdir,tmpname);	close(creat(tfname, 0600));	tf = open(tfname, 2);	if(tf < 0) {		fprintf(stderr, "ar: cannot create temp file\n");		done(1);	}	if (write(tf, ARMAG, SARMAG) != SARMAG)		wrerr();}getaf(){	char mbuf[SARMAG];	af = open(arnam, 0);	if(af < 0)		return(1);	if (read(af, mbuf, SARMAG) != SARMAG || strncmp(mbuf, ARMAG, SARMAG)) {		fprintf(stderr, "ar: %s not in archive format\n", arnam);		done(1);	}	return(0);}getqf(){

⌨️ 快捷键说明

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