diffdir.c

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

C
482
字号
#ifndef lintstatic char *sccsid = "@(#)diffdir.c	4.1	ULTRIX	7/17/90";#endif lint/************************************************************************ *									* *			Copyright (c) 1988 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 *      -------------------- * *	10-Nov-88		Tim N *			Took 4.3-5 sources and added changes made to *			previous version's sources.  Includes DL's *			eight bit work. *			This 4.3-5 source had id: *				"@(#)diffdir.c 4.11 (Berkeley) 10/22/87"; ************************************************************************/#include "diff.h"/* * diff - directory comparison */#define	d_flags	d_ino#define	ONLY	1		/* Only in this directory */#define	SAME	2		/* Both places and same */#define	DIFFER	4		/* Both places and different */#define	DIRECT	8		/* Directory */#define	ismulti(c)	((c & 0xff) >= 0xa0 && (c & 0xff) <= 0xff)struct dir {	u_long	d_ino;	short	d_reclen;	short	d_namlen;	char	*d_entry;};struct	dir *setupdir();int	header;static int	dirstatus;		/* exit status from diffdir */extern int	status;char	title[2*BUFSIZ], *etitle;diffdir(argv)	char **argv;{	register struct dir *d1, *d2;	struct dir *dir1, *dir2;	register int i;	int cmp;	if (opt == D_IFDEF) {		fprintf(stderr, "diff: can't specify -D with directories\n");		done();	}	if (opt == D_EDIT && (sflag || lflag))		fprintf(stderr,		    "diff: warning: shouldn't give -s or -l with -e\n");	title[0] = 0;	strcpy(title, "diff ");	for (i = 1; diffargv[i+2]; i++) {		if (!strcmp(diffargv[i], "-"))			continue;	/* was -S, dont look silly */		strcat(title, diffargv[i]);		strcat(title, " ");	}	for (etitle = title; *etitle; etitle++)		;	setfile(&file1, &efile1, file1);	setfile(&file2, &efile2, file2);	argv[0] = file1;	argv[1] = file2;	dir1 = setupdir(file1);	dir2 = setupdir(file2);	d1 = dir1; d2 = dir2;	while (d1->d_entry != 0 || d2->d_entry != 0) {		if (d1->d_entry && useless(d1->d_entry)) {			d1++;			continue;		}		if (d2->d_entry && useless(d2->d_entry)) {			d2++;			continue;		}		if (d1->d_entry == 0)			cmp = 1;		else if (d2->d_entry == 0)			cmp = -1;		else			cmp = strcmp(d1->d_entry, d2->d_entry);		if (cmp < 0) {			if (lflag)				d1->d_flags |= ONLY;			else if (opt == 0 || opt == 2)				only(d1, 1);			d1++;			dirstatus |= 1;		} else if (cmp == 0) {			compare(d1);			d1++;			d2++;		} else {			if (lflag)				d2->d_flags |= ONLY;			else if (opt == 0 || opt == 2)				only(d2, 2);			d2++;			dirstatus |= 1;		}	}	if (lflag) {		scanpr(dir1, ONLY, "Only in %.*s", file1, efile1, 0, 0);		scanpr(dir2, ONLY, "Only in %.*s", file2, efile2, 0, 0);		scanpr(dir1, SAME, "Common identical files in %.*s and %.*s",		    file1, efile1, file2, efile2);		scanpr(dir1, DIFFER, "Binary files which differ in %.*s and %.*s",		    file1, efile1, file2, efile2);		scanpr(dir1, DIRECT, "Common subdirectories of %.*s and %.*s",		    file1, efile1, file2, efile2);	}	if (rflag) {		if (header && lflag)			printf("\f");		for (d1 = dir1; d1->d_entry; d1++)  {			if ((d1->d_flags & DIRECT) == 0)				continue;			strcpy(efile1, d1->d_entry);			strcpy(efile2, d1->d_entry);			calldiff(0);		}	}	status = dirstatus;}setfile(fpp, epp, file)	char **fpp, **epp;	char *file;{	register char *cp;	*fpp = malloc(BUFSIZ);	if (*fpp == 0) {		fprintf(stderr, "diff: ran out of memory\n");		exit(1);	}	strcpy(*fpp, file);	for (cp = *fpp; *cp; cp++)		continue;	*cp++ = '/';	*epp = cp;}scanpr(dp, test, title, file1, efile1, file2, efile2)	register struct dir *dp;	int test;	char *title, *file1, *efile1, *file2, *efile2;{	int titled = 0;	for (; dp->d_entry; dp++) {		if ((dp->d_flags & test) == 0)			continue;		if (titled == 0) {			if (header == 0)				header = 1;			else				printf("\n");			printf(title,			    efile1 - file1 - 1, file1,			    efile2 - file2 - 1, file2);			printf(":\n");			titled = 1;		}		printf("\t%s\n", dp->d_entry);	}}only(dp, which)	struct dir *dp;	int which;{	char *file = which == 1 ? file1 : file2;	char *efile = which == 1 ? efile1 : efile2;	printf("Only in %.*s: %s\n", efile - file - 1, file, dp->d_entry);	}int	entcmp();struct dir *setupdir(cp)	char *cp;{	register struct dir *dp = 0, *ep;	register struct direct *rp;	register int nitems, n;	DIR *dirp;	dirp = opendir(cp);	if (dirp == NULL) {		fprintf(stderr, "diff: ");		perror(cp);		done();	}	nitems = 0;	dp = (struct dir *)malloc(sizeof (struct dir));	if (dp == 0) {		fprintf(stderr, "diff: ran out of memory\n");		done();	}	while (rp = readdir(dirp)) {		ep = &dp[nitems++];		ep->d_reclen = rp->d_reclen;		ep->d_namlen = rp->d_namlen;		ep->d_entry = 0;		ep->d_flags = 0;		if (ep->d_namlen > 0) {			ep->d_entry = malloc(ep->d_namlen + 1);			if (ep->d_entry == 0) {				fprintf(stderr, "diff: out of memory\n");				done();			}			strcpy(ep->d_entry, rp->d_name);		}		dp = (struct dir *)realloc((char *)dp,			(nitems + 1) * sizeof (struct dir));		if (dp == 0) {			fprintf(stderr, "diff: ran out of memory\n");			done();		}	}	dp[nitems].d_entry = 0;		/* delimiter */	closedir(dirp);	qsort(dp, nitems, sizeof (struct dir), entcmp);	return (dp);}entcmp(d1, d2)	struct dir *d1, *d2;{	return (strcmp(d1->d_entry, d2->d_entry));}compare(dp)	register struct dir *dp;{	register int i, j;	int f1, f2, fmt1, fmt2;	struct stat stb1, stb2;	int flag = 0;	char buf1[BUFSIZ], buf2[BUFSIZ];	strcpy(efile1, dp->d_entry);	strcpy(efile2, dp->d_entry);	f1 = open(file1, 0);	if (f1 < 0) {		perror(file1);		return;	}	f2 = open(file2, 0);	if (f2 < 0) {		perror(file2);		close(f1);		return;	}	fstat(f1, &stb1); fstat(f2, &stb2);	fmt1 = stb1.st_mode & S_IFMT;	fmt2 = stb2.st_mode & S_IFMT;	if (fmt1 != S_IFREG || fmt2 != S_IFREG) {		if (fmt1 == fmt2) {			if (fmt1 != S_IFDIR && stb1.st_rdev == stb2.st_rdev)				goto same;			if (fmt1 == S_IFDIR) {				dp->d_flags = DIRECT;				if (lflag || opt == D_EDIT)					goto closem;				printf("Common subdirectories: %s and %s\n",				    file1, file2);				goto closem;			}		}		goto notsame;	}	if (stb1.st_size != stb2.st_size)		goto notsame;	for (;;) {		i = read(f1, buf1, BUFSIZ);		j = read(f2, buf2, BUFSIZ);		if (i < 0 || j < 0 || i != j)			goto notsame;		if (i == 0 && j == 0)			goto same;		for (j = 0; j < i; j++)			if (buf1[j] != buf2[j])				goto notsame;	}same:	status = 0;	if (sflag == 0)		goto closem;	if (lflag)		dp->d_flags = SAME;	else		printf("Files %s and %s are identical\n", file1, file2);	goto closem;notsame:	dirstatus |= 1;	if (!ascii(f1) || !ascii(f2)) {		if (lflag)			dp->d_flags |= DIFFER;		else if (opt == D_NORMAL || opt == D_CONTEXT)			printf("Binary files %s and %s differ\n",			    file1, file2);		goto closem;	}	close(f1); close(f2);	status = 1;	if (lflag)		calldiff(title);	else {		if (opt == D_EDIT) {			printf("ed - %s << '-*-END-*-'\n", dp->d_entry);			calldiff(0);		} else {			printf("%s%s %s\n", title, file1, file2);			calldiff(0);		}		if (opt == D_EDIT)			printf("w\nq\n-*-END-*-\n");	}	return;closem:	close(f1); close(f2);}char	*prargs[] = { "pr", "-h", 0, "-f", 0, 0 };calldiff(wantpr)	char *wantpr;{	int pid, lstatus, lstatus2, pv[2];	prargs[2] = wantpr;	fflush(stdout);	if (wantpr) {		(void)sprintf(etitle, "%s %s", file1, file2);		pipe(pv);		pid = fork();		if (pid == -1) {			fprintf(stderr, "No more processes");			done();		}		if (pid == 0) {			close(0);			dup(pv[0]);			close(pv[0]);			close(pv[1]);			execv(pr+4, prargs);			execv(pr, prargs);			perror(pr);			done();		}	}	pid = fork();	if (pid == -1) {		fprintf(stderr, "diff: No more processes\n");		done();	}	if (pid == 0) {		if (wantpr) {			close(1);			dup(pv[1]);			close(pv[0]);			close(pv[1]);		}		execv(diff+4, diffargv);		execv(diff, diffargv);		perror(diff);		done();	}	if (wantpr) {		close(pv[0]);		close(pv[1]);	}	while (wait(&lstatus) != pid)		continue;	while (wait(&lstatus2) != -1)		continue;/*	if ((lstatus >> 8) >= 2)		done();*/	dirstatus |= lstatus >> 8;}#include <a.out.h>ascii(f)	int f;{		char buf[BUFSIZ];	register int cnt, c;	register char *cp;	lseek(f, (long)0, 0);	cnt = read(f, buf, BUFSIZ);#ifdef mips	if (cnt >= FILHSZ + AOUTHSZ) {		AOUTHDR hdr;		hdr = *(AOUTHDR *)&buf[FILHSZ];		if (!N_BADMAG(hdr))			return (0);	}#else	if (cnt >= sizeof (struct exec)) {		struct exec hdr;		hdr = *(struct exec *)buf;		if (!N_BADMAG(hdr))			return (0);	}#endif mips	cp = buf;	while (--cnt >= 0)	{			c = *cp++ & 0377;		if (!(c & 0200))			continue;		if (ismulti(c))			continue;		return (0);	}	return (1);}/* * THIS IS CRUDE. */useless(cp)register char *cp;{	if (cp[0] == '.') {		if (cp[1] == '\0')			return (1);	/* directory "." */		if (cp[1] == '.' && cp[2] == '\0')			return (1);	/* directory ".." */	}	if (start && strcmp(start, cp) > 0)		return (1);	return (0);}

⌨️ 快捷键说明

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