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

📄 ar.c

📁 unix v7是最后一个广泛发布的研究型UNIX版本
💻 C
字号:
#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <ar.h>#include <signal.h>struct	stat	stbuf;struct	ar_hdr	arbuf;#define	SKIP	1#define	IODD	2#define	OODD	4#define	HEAD	8char	*man	=	{ "mrxtdpq" };char	*opt	=	{ "uvnbail" };int	signum[] = {SIGHUP, SIGINT, SIGQUIT, 0};int	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	*tmpnam		=	{ "/tmp/vXXXXX" };char	*tmp1nam	=	{ "/tmp/v1XXXXX" };char	*tmp2nam	=	{ "/tmp/v2XXXXX" };char	*tfnam;char	*tf1nam;char	*tf2nam;char	*file;char	name[16];int	af;int	tf;int	tf1;int	tf2;int	qf;int	bastate;char	buf[512];char	*trim();char	*mktemp();char	*ctime();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];	for(cp = argv[1]; *cp; cp++)	switch(*cp) {	case 'l':	case 'v':	case 'u':	case 'n':	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']) {		tmpnam = "vXXXXX";		tmp1nam = "v1XXXXX";		tmp2nam = "v2XXXXX";		}	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();	while(!getdir()) {		bamatch();		if(namc == 0 || 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 <= arbuf.ar_date) {					close(f);					goto cp;				}			mesg('r');			copyfil(af, -1, IODD+SKIP);			movefil(f);			continue;		}	cp:		mesg('c');		copyfil(af, tf, IODD+OODD+HEAD);	}	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;	if(getaf())		noar();	while(!getdir()) {		if(namc == 0 || match()) {			f = creat(file, arbuf.ar_mode & 0777);			if(f < 0) {				fprintf(stderr, "ar: %s cannot create\n", file);				goto sk;			}			mesg('x');			copyfil(af, f, IODD);			close(f);			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();	tf2nam = mktemp(tmp2nam);	close(creat(tf2nam, 0600));	tf2 = open(tf2nam, 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);	}	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(){	static mbuf = ARMAG;	tfnam = mktemp(tmpnam);	close(creat(tfnam, 0600));	tf = open(tfnam, 2);	if(tf < 0) {		fprintf(stderr, "ar: cannot create temp file\n");		done(1);	}	if (write(tf, (char *)&mbuf, sizeof(int)) != sizeof(int))		wrerr();}getaf(){	int mbuf;	af = open(arnam, 0);	if(af < 0)		return(1);	if (read(af, (char *)&mbuf, sizeof(int)) != sizeof(int) || mbuf!=ARMAG) {		fprintf(stderr, "ar: %s not in archive format\n", arnam);		done(1);	}	return(0);}getqf(){	int mbuf;	if ((qf = open(arnam, 2)) < 0) {		if(!flg['c'-'a'])			fprintf(stderr, "ar: creating %s\n", arnam);		close(creat(arnam, 0666));		if ((qf = open(arnam, 2)) < 0) {			fprintf(stderr, "ar: cannot create %s\n", arnam);			done(1);		}		mbuf = ARMAG;		if (write(qf, (char *)&mbuf, sizeof(int)) != sizeof(int))			wrerr();	}	else if (read(qf, (char *)&mbuf, sizeof(int)) != sizeof(int)		|| mbuf!=ARMAG) {		fprintf(stderr, "ar: %s not in archive format\n", arnam);		done(1);	}}usage(){	printf("usage: ar [%s][%s] archive files ...\n", opt, man);	done(1);}noar(){	fprintf(stderr, "ar: %s does not exist\n", arnam);	done(1);}sigdone(){	done(100);}done(c){	if(tfnam)		unlink(tfnam);	if(tf1nam)		unlink(tf1nam);	if(tf2nam)		unlink(tf2nam);	exit(c);}notfound(){	register i, n;	n = 0;	for(i=0; i<namc; i++)		if(namv[i]) {			fprintf(stderr, "ar: %s not found\n", namv[i]);			n++;		}	return(n);}morefil(){	register i, n;	n = 0;	for(i=0; i<namc; i++)		if(namv[i])			n++;	return(n);}cleanup(){	register i, f;	for(i=0; i<namc; i++) {		file = namv[i];		if(file == 0)			continue;		namv[i] = 0;		mesg('a');		f = stats();		if(f < 0) {			fprintf(stderr, "ar: %s cannot open\n", file);			continue;		}		movefil(f);	}	install();}install(){	register i;	for(i=0; signum[i]; i++)		signal(signum[i], SIG_IGN);	if(af < 0)		if(!flg['c'-'a'])			fprintf(stderr, "ar: creating %s\n", arnam);	close(af);	af = creat(arnam, 0666);	if(af < 0) {		fprintf(stderr, "ar: cannot create %s\n", arnam);		done(1);	}	if(tfnam) {		lseek(tf, 0l, 0);		while((i = read(tf, buf, 512)) > 0)			if (write(af, buf, i) != i)				wrerr();	}	if(tf2nam) {		lseek(tf2, 0l, 0);		while((i = read(tf2, buf, 512)) > 0)			if (write(af, buf, i) != i)				wrerr();	}	if(tf1nam) {		lseek(tf1, 0l, 0);		while((i = read(tf1, buf, 512)) > 0)			if (write(af, buf, i) != i)				wrerr();	}}/* * insert the file 'file' * into the temporary file */movefil(f){	register char *cp;	register i;	cp = trim(file);	for(i=0; i<14; i++)		if(arbuf.ar_name[i] = *cp)			cp++;	arbuf.ar_size = stbuf.st_size;	arbuf.ar_date = stbuf.st_mtime;	arbuf.ar_uid = stbuf.st_uid;	arbuf.ar_gid = stbuf.st_gid;	arbuf.ar_mode = stbuf.st_mode;	copyfil(f, tf, OODD+HEAD);	close(f);}stats(){	register f;	f = open(file, 0);	if(f < 0)		return(f);	if(fstat(f, &stbuf) < 0) {		close(f);		return(-1);	}	return(f);}/* * copy next file * size given in arbuf */copyfil(fi, fo, flag){	register i, o;	int pe;	if(flag & HEAD)		if (write(fo, (char *)&arbuf, sizeof arbuf) != sizeof arbuf)			wrerr();	pe = 0;	while(arbuf.ar_size > 0) {		i = o = 512;		if(arbuf.ar_size < i) {			i = o = arbuf.ar_size;			if(i&1) {				if(flag & IODD)					i++;				if(flag & OODD)					o++;			}		}		if(read(fi, buf, i) != i)			pe++;		if((flag & SKIP) == 0)			if (write(fo, buf, o) != o)				wrerr();		arbuf.ar_size -= 512;	}	if(pe)		phserr();}getdir(){	register i;	i = read(af, (char *)&arbuf, sizeof arbuf);	if(i != sizeof arbuf) {		if(tf1nam) {			i = tf;			tf = tf1;			tf1 = i;		}		return(1);	}	for(i=0; i<14; i++)		name[i] = arbuf.ar_name[i];	file = name;	return(0);}match(){	register i;	for(i=0; i<namc; i++) {		if(namv[i] == 0)			continue;		if(strcmp(trim(namv[i]), file) == 0) {			file = namv[i];			namv[i] = 0;			return(1);		}	}	return(0);}bamatch(){	register f;	switch(bastate) {	case 1:		if(strcmp(file, ponam) != 0)			return;		bastate = 2;		if(flg['a'-'a'])			return;	case 2:		bastate = 0;		tf1nam = mktemp(tmp1nam);		close(creat(tf1nam, 0600));		f = open(tf1nam, 2);		if(f < 0) {			fprintf(stderr, "ar: cannot create second temp\n");			return;		}		tf1 = tf;		tf = f;	}}phserr(){	fprintf(stderr, "ar: phase error on %s\n", file);}mesg(c){	if(flg['v'-'a'])		if(c != 'c' || flg['v'-'a'] > 1)			printf("%c - %s\n", c, file);}char *trim(s)char *s;{	register char *p1, *p2;	for(p1 = s; *p1; p1++)		;	while(p1 > s) {		if(*--p1 != '/')			break;		*p1 = 0;	}	p2 = s;	for(p1 = s; *p1; p1++)		if(*p1 == '/')			p2 = p1+1;	return(p2);}#define	IFMT	060000#define	ISARG	01000#define	LARGE	010000#define	SUID	04000#define	SGID	02000#define	ROWN	0400#define	WOWN	0200#define	XOWN	0100#define	RGRP	040#define	WGRP	020#define	XGRP	010#define	ROTH	04#define	WOTH	02#define	XOTH	01#define	STXT	01000longt(){	register char *cp;	pmode();	printf("%3d/%1d", arbuf.ar_uid, arbuf.ar_gid);	printf("%7D", arbuf.ar_size);	cp = ctime(&arbuf.ar_date);	printf(" %-12.12s %-4.4s ", cp+4, cp+20);}int	m1[] = { 1, ROWN, 'r', '-' };int	m2[] = { 1, WOWN, 'w', '-' };int	m3[] = { 2, SUID, 's', XOWN, 'x', '-' };int	m4[] = { 1, RGRP, 'r', '-' };int	m5[] = { 1, WGRP, 'w', '-' };int	m6[] = { 2, SGID, 's', XGRP, 'x', '-' };int	m7[] = { 1, ROTH, 'r', '-' };int	m8[] = { 1, WOTH, 'w', '-' };int	m9[] = { 2, STXT, 't', XOTH, 'x', '-' };int	*m[] = { m1, m2, m3, m4, m5, m6, m7, m8, m9};pmode(){	register int **mp;	for (mp = &m[0]; mp < &m[9];)		select(*mp++);}select(pairp)int *pairp;{	register int n, *ap;	ap = pairp;	n = *ap++;	while (--n>=0 && (arbuf.ar_mode&*ap++)==0)		ap++;	putchar(*ap);}wrerr(){	perror("ar write error");	done(1);}

⌨️ 快捷键说明

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