diff options
author | 2003-06-25 01:20:52 +0000 | |
---|---|---|
committer | 2003-06-25 01:20:52 +0000 | |
commit | ae8d569b0d3206631092f123a4796c817bc7adf6 (patch) | |
tree | 88fd655c2dfd2b3906638ef69877bd8bfa0b9436 /usr.bin/diff/diffdir.c | |
parent | fix _set_ functions as found while debugging an@stp (diff) | |
download | wireguard-openbsd-ae8d569b0d3206631092f123a4796c817bc7adf6.tar.xz wireguard-openbsd-ae8d569b0d3206631092f123a4796c817bc7adf6.zip |
4.3reno diff. This is free because of the Caldera license. Nasty, but a
place to start.
Diffstat (limited to 'usr.bin/diff/diffdir.c')
-rw-r--r-- | usr.bin/diff/diffdir.c | 419 |
1 files changed, 419 insertions, 0 deletions
diff --git a/usr.bin/diff/diffdir.c b/usr.bin/diff/diffdir.c new file mode 100644 index 00000000000..7be6578da6f --- /dev/null +++ b/usr.bin/diff/diffdir.c @@ -0,0 +1,419 @@ +static char *sccsid = "@(#)diffdir.c 4.12 (Berkeley) 4/30/89"; + +#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 */ + +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 -I 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, *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: + 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); + anychange = 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; + register char *cp; + + lseek(f, (long)0, 0); + cnt = read(f, buf, BUFSIZ); + if (cnt >= sizeof (struct exec)) { + struct exec hdr; + hdr = *(struct exec *)buf; + if (!N_BADMAG(hdr)) + return (0); + } + cp = buf; + while (--cnt >= 0) + if (*cp++ & 0200) + 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); +} |