ar.c

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

C
916
字号
	char mbuf[SARMAG];	if ((qf = open(arnam, 2)) < 0) {		if(!flg['c'-'a'])			fprintf(stderr, "ar: creating %s\n", arnam);		if ((qf = creat(arnam, 0666)) < 0) {			fprintf(stderr, "ar: cannot create %s\n", arnam);			done(1);		}		if (write(qf, ARMAG, SARMAG) != SARMAG)			wrerr();	} else if (read(qf, mbuf, SARMAG) != SARMAG		|| strncmp(mbuf, ARMAG, SARMAG)) {		fprintf(stderr, "ar: %s not in archive format\n", arnam);		done(1);	}}usage(){	printf("usage: ar [%s][%s] archive files ...\n", man, opt);	done(1);}noar(){	fprintf(stderr, "ar: %s does not exist\n", arnam);	done(1);}voidsigdone(){	done(100);}done(c){	if(tfname)		unlink(tfname);	if(tf1name)		unlink(tf1name);	if(tf2name)		unlink(tf2name);	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;	truncate++;	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(tfname) {		lseek(tf, 0l, 0);		while((i = read(tf, buf, sizeof(buf))) > 0)			if (write(af, buf, i) != i)				wrerr();	}	if(tf2name) {		lseek(tf2, 0l, 0);		while((i = read(tf2, buf, sizeof(buf))) > 0)			if (write(af, buf, i) != i)				wrerr();	}	if(tf1name) {		lseek(tf1, 0l, 0);		while((i = read(tf1, buf, sizeof(buf))) > 0)			if (write(af, buf, i) != i)				wrerr();	}}/* * insert the file 'file' * into the temporary file */movefil(f){	char buf[sizeof(arbuf)+1];	sprintf(buf, "%-16s%-12ld%-6u%-6u%-8o%-10ld%-2s",	   trim(file),	   stbuf.st_mtime,	   (unsigned short) stbuf.st_uid,		/* slr002 */	   (unsigned short) stbuf.st_gid,		/* slr002 */	   stbuf.st_mode,	   stbuf.st_size,	   ARFMAG);	strncpy((char *)&arbuf, buf, sizeof(arbuf));	larbuf.lar_size = stbuf.st_size;	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) {		for (i=sizeof(arbuf.ar_name)-1; i>=0; i--) {			if (arbuf.ar_name[i]==' ')				continue;			else if (arbuf.ar_name[i]=='\0')				arbuf.ar_name[i] = ' ';			else				break;		}		if (write(fo, (char *)&arbuf, sizeof arbuf) != sizeof arbuf)			wrerr();	}	pe = 0;	while(larbuf.lar_size > 0) {		i = o = sizeof(buf);		if(larbuf.lar_size < i) {			i = o = larbuf.lar_size;			if(i&1) {				buf[i] = '\n';				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();		larbuf.lar_size -= sizeof(buf);	}	if(pe)		phserr();}getdir(){	register char *cp;	register i;	i = read(af, (char *)&arbuf, sizeof arbuf);	if(i != sizeof arbuf) {		if(tf1name) {			i = tf;			tf = tf1;			tf1 = i;		}		return(1);	}	if (strncmp(arbuf.ar_fmag, ARFMAG, sizeof(arbuf.ar_fmag))) {		fprintf(stderr, "ar: malformed archive (at %ld)\n", lseek(af, 0L, 1));		done(1);	}	cp = arbuf.ar_name + sizeof(arbuf.ar_name);	while (*--cp==' ')		;	*++cp = '\0';	strncpy(name, arbuf.ar_name, sizeof(arbuf.ar_name));	file = name;	strncpy(larbuf.lar_name, name, sizeof(larbuf.lar_name));	sscanf(arbuf.ar_date, "%ld", &larbuf.lar_date);	sscanf(arbuf.ar_uid, "%hd", &larbuf.lar_uid);	sscanf(arbuf.ar_gid, "%hd", &larbuf.lar_gid);	sscanf(arbuf.ar_mode, "%ho", &larbuf.lar_mode);	sscanf(arbuf.ar_size, "%ld", &larbuf.lar_size);	return(0);}/* rcmd_match() * * This function is just for use by rcmd().  This does the same job * as calling match() which calls trim() but it leaves the * filename in the original state so it can be used later for the open.*/rcmd_match(){	register i;	register char *p1, *p2;	for(i=0; i<namc; i++) {		if(namv[i] == 0)			continue;		/* trim the name to just the filename and compare only		 * 15 characters if needed.  But, we need to leave		 * the full filename before returning to rcmd which will		 * use the filename to do the open.		*/		/* Strip trailing slashes */		for(p1 = namv[i]; *p1; p1++)		    ;		while(p1 > namv[i]){		    if(*--p1 != '/')			break;		    *p1 = 0;		}		/* Find last component of path; do not zap the path */		p2 = namv[i];		for(p1 = namv[i]; *p1; p1++)		    if(*p1 == '/')			p2 = p1+1;		/* p2 now points to just the filename of the file spec.		 * We only compare the characters that will fit in the		 * space for ar's filenames.  Later on (if this matches)		 * rcmd() will call movefil() which calls trim() and it		 * will really truncate the filename when we don't need the		 * full spec any more.		*/		if(strncmp(p2, file, (sizeof(arbuf.ar_name) - 1)) == 0) {		    file = namv[i];		    namv[i] = 0;		    return(1);		}	}	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;		if(flg['l'-'a'])		    tf1name = mktemp(tmp1name);		else		    tf1name = tempnam(tdir,tmp1name);		close(creat(tf1name, 0600));		f = open(tf1name, 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;	/* Strip trailing slashes */	for(p1 = s; *p1; p1++)		;	while(p1 > s) {		if(*--p1 != '/')			break;		*p1 = 0;	}	/* Find last component of path; do not zap the path */	p2 = s;	for(p1 = s; *p1; p1++)		if(*p1 == '/')			p2 = p1+1;	/*	 * Truncate name if too long, only if we are doing an 'add'	 * type operation. We only allow 15 cause rest of ar	 * isn't smart enough to deal with non-null terminated	 * names.  Need an exit status convention...	 * Need yet another new archive format...	 */	if (truncate && strlen(p2) > sizeof(arbuf.ar_name) - 1) {		fprintf(stderr, "ar: filename %s truncated to ", p2);		*(p2 + sizeof(arbuf.ar_name) - 1) = '\0';		fprintf(stderr, "%s\n", p2);	}	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("%5d/%-5d", larbuf.lar_uid, larbuf.lar_gid);	printf(" %6ld", larbuf.lar_size);	cp = ctime(&larbuf.lar_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 && (larbuf.lar_mode&*ap++)==0)		ap++;	putchar(*ap);}wrerr(){	perror("ar write error");	done(1);}

⌨️ 快捷键说明

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