version 1.30, 2003/07/08 04:51:30 |
version 1.31, 2003/07/09 00:07:44 |
|
|
|
|
#include <sys/types.h> |
#include <sys/types.h> |
#include <sys/stat.h> |
#include <sys/stat.h> |
|
#include <sys/wait.h> |
|
|
#include <ctype.h> |
#include <ctype.h> |
#include <err.h> |
#include <err.h> |
#include <fcntl.h> |
#include <fcntl.h> |
#include <libgen.h> |
#include <libgen.h> |
#include <paths.h> |
|
#include <signal.h> |
#include <signal.h> |
#include <stdio.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include <stdlib.h> |
|
|
#include <unistd.h> |
#include <unistd.h> |
|
|
#include "diff.h" |
#include "diff.h" |
|
#include "pathnames.h" |
|
|
/* |
/* |
* diff - compare two files. |
* diff - compare two files. |
|
|
0xfd, 0xfe, 0xff |
0xfd, 0xfe, 0xff |
}; |
}; |
|
|
void |
int |
diffreg(char *ofile1, char *ofile2, int flags) |
diffreg(char *ofile1, char *ofile2, int flags) |
{ |
{ |
char *file1 = ofile1; |
char *file1 = ofile1; |
char *file2 = ofile2; |
char *file2 = ofile2; |
FILE *f1 = NULL; |
FILE *f1 = NULL; |
FILE *f2 = NULL; |
FILE *f2 = NULL; |
int i; |
int rval = D_SAME; |
|
int i, ostdout = -1; |
|
pid_t pid = -1; |
|
|
anychange = 0; |
anychange = 0; |
chrtran = (iflag ? cup2low : clow2low); |
chrtran = (iflag ? cup2low : clow2low); |
|
|
|
|
switch (files_differ(f1, f2, flags)) { |
switch (files_differ(f1, f2, flags)) { |
case 0: |
case 0: |
goto same; |
goto closem; |
case 1: |
case 1: |
break; |
break; |
default: |
default: |
|
|
* Files certainly differ at this point; set status accordingly |
* Files certainly differ at this point; set status accordingly |
*/ |
*/ |
status |= 1; |
status |= 1; |
if (format == D_BRIEF) { |
rval = D_DIFFER; |
printf("Files %s and %s differ\n", file1, file2); |
if (!asciifile(f1) || !asciifile(f2)) { |
|
rval = D_BINARY; |
goto closem; |
goto closem; |
} |
} |
if (flags & D_HEADER) { |
if (format == D_BRIEF) |
if (format == D_EDIT) |
|
printf("ed - %s << '-*-END-*-'\n", basename(file1)); |
|
else |
|
printf("%s %s %s\n", diffargs, file1, file2); |
|
} |
|
if (!asciifile(f1) || !asciifile(f2)) { |
|
printf("Binary files %s and %s differ\n", file1, file2); |
|
goto closem; |
goto closem; |
|
if (lflag) { |
|
/* redirect stdout to pr */ |
|
int pfd[2]; |
|
char *header; |
|
char *prargv[] = { "pr", "-h", NULL, "-f", NULL }; |
|
|
|
easprintf(&header, "%s %s %s", diffargs, file1, file2); |
|
prargv[2] = header; |
|
fflush(stdout); |
|
rewind(stdout); |
|
pipe(pfd); |
|
switch ((pid = fork())) { |
|
case -1: |
|
warnx("No more processes"); |
|
status |= 2; |
|
free(header); |
|
return (D_ERROR); |
|
case 0: |
|
/* child */ |
|
if (pfd[0] != STDIN_FILENO) { |
|
dup2(pfd[0], STDIN_FILENO); |
|
close(pfd[0]); |
|
} |
|
close(pfd[1]); |
|
execv(_PATH_PR, prargv); |
|
_exit(127); |
|
default: |
|
/* parent */ |
|
if (pfd[1] != STDOUT_FILENO) { |
|
ostdout = dup(STDOUT_FILENO); |
|
dup2(pfd[1], STDOUT_FILENO); |
|
close(pfd[1]); |
|
} |
|
close(pfd[0]); |
|
rewind(stdout); |
|
free(header); |
|
} |
|
} else { |
|
if (flags & D_HEADER) { |
|
if (format == D_EDIT) |
|
printf("ed - %s << '-*-END-*-'\n", |
|
basename(file1)); |
|
else |
|
printf("%s %s %s\n", diffargs, file1, file2); |
|
} |
} |
} |
prepare(0, f1); |
prepare(0, f1); |
prepare(1, f2); |
prepare(1, f2); |
|
|
ixnew = erealloc(ixnew, (len[1] + 2) * sizeof(long)); |
ixnew = erealloc(ixnew, (len[1] + 2) * sizeof(long)); |
check(file1, f1, file2, f2); |
check(file1, f1, file2, f2); |
output(file1, f1, file2, f2); |
output(file1, f1, file2, f2); |
if ((flags & D_HEADER) && format == D_EDIT) |
if (ostdout != -1) { |
printf("w\nq\n-*-END-*-\n"); |
int wstatus; |
same: |
|
if (anychange == 0 && sflag != 0) |
|
printf("Files %s and %s are identical\n", file1, file2); |
|
|
|
|
/* close the pipe to pr and restore stdout */ |
|
fflush(stdout); |
|
rewind(stdout); |
|
if (ostdout != STDOUT_FILENO) { |
|
close(STDOUT_FILENO); |
|
dup2(ostdout, STDOUT_FILENO); |
|
close(ostdout); |
|
} |
|
waitpid(pid, &wstatus, 0); |
|
} else if ((flags & D_HEADER) && format == D_EDIT) |
|
printf("w\nq\n-*-END-*-\n"); |
closem: |
closem: |
if (f1 != NULL) |
if (f1 != NULL) |
fclose(f1); |
fclose(f1); |
|
|
tempfiles[1] = NULL; |
tempfiles[1] = NULL; |
} else if (file2 != ofile2) |
} else if (file2 != ofile2) |
free(file2); |
free(file2); |
|
return (rval); |
} |
} |
|
|
/* |
/* |
|
|
signal(SIGINT, quit); |
signal(SIGINT, quit); |
signal(SIGPIPE, quit); |
signal(SIGPIPE, quit); |
signal(SIGTERM, quit); |
signal(SIGTERM, quit); |
|
signal(SIGPIPE, SIG_IGN); |
ofd = mkstemp(tempfile); |
ofd = mkstemp(tempfile); |
if (ofd < 0) |
if (ofd < 0) |
return (NULL); |
return (NULL); |
|
|
splice(char *dir, char *file) |
splice(char *dir, char *file) |
{ |
{ |
char *tail, *buf; |
char *tail, *buf; |
size_t len; |
|
|
|
tail = strrchr(file, '/'); |
tail = strrchr(file, '/'); |
if (tail == NULL) |
if (tail == NULL) |
tail = file; |
tail = file; |
else |
else |
tail++; |
tail++; |
len = strlen(dir) + 1 + strlen(tail) + 1; |
easprintf(&buf, "%s/%s", dir, tail); |
buf = emalloc(len); |
|
snprintf(buf, len, "%s/%s", dir, tail); |
|
return (buf); |
return (buf); |
} |
} |
|
|
|
|
if ((format == D_EDIT || format == D_REVERSE) && c <= d) |
if ((format == D_EDIT || format == D_REVERSE) && c <= d) |
puts("."); |
puts("."); |
if (inifdef) { |
if (inifdef) { |
fprintf(stdout, "#endif /* %s */\n", ifdefname); |
printf("#endif /* %s */\n", ifdefname); |
inifdef = 0; |
inifdef = 0; |
} |
} |
} |
} |
|
|
return; |
return; |
if (format == D_IFDEF) { |
if (format == D_IFDEF) { |
if (inifdef) { |
if (inifdef) { |
fprintf(stdout, "#else /* %s%s */\n", |
printf("#else /* %s%s */\n", |
oldfile == 1 ? "!" : "", ifdefname); |
oldfile == 1 ? "!" : "", ifdefname); |
} else { |
} else { |
if (oldfile) |
if (oldfile) |
fprintf(stdout, "#ifndef %s\n", ifdefname); |
printf("#ifndef %s\n", ifdefname); |
else |
else |
fprintf(stdout, "#ifdef %s\n", ifdefname); |
printf("#ifdef %s\n", ifdefname); |
} |
} |
inifdef = 1 + oldfile; |
inifdef = 1 + oldfile; |
} |
} |