6 #define DIRECTORY(s) ((s)->qid.type&QTDIR)
7 #define REGULAR_FILE(s) ((s)->type == 'M' && !DIRECTORY(s))
11 static char *tmp[] = {"/tmp/diff1XXXXXXXXXXX", "/tmp/diff2XXXXXXXXXXX"};
13 static char *progname;
14 static char usage[] = "diff [ -acefmnbwr ] file1 ... file2\n";
19 while (whichtmp > 0) {
21 remove(tmp[whichtmp]);
42 panic(int status, char *fmt, ...)
48 fprint(2, "%s: ", progname);
58 catch(void *a, char *msg)
66 mkpathname(char *pathname, char *path, char *name)
68 if (strlen(path) + strlen(name) > MAXPATHLEN) {
69 panic(0, "pathname %s/%s too long\n", path, name);
72 sprint(pathname, "%s/%s", path, name);
77 mktmpfile(int input, Dir **sb)
85 p = mktemp(tmp[whichtmp++]);
86 fd = create(p, OWRITE, 0600);
88 fd = mkstemp(p=tmp[whichtmp++]);
90 panic(mflag ? 0: 2, "cannot create %s: %r\n", p);
93 while ((i = read(input, buf, sizeof(buf))) > 0) {
94 if ((i = write(fd, buf, i)) < 0)
100 panic(mflag ? 0: 2, "cannot read/write %s: %r\n", p);
107 statfile(char *file, Dir **sb)
114 if (strcmp(file, "-") || (dir = dirfstat(0)) == nil) {
115 panic(mflag ? 0: 2, "cannot stat %s: %r\n", file);
119 return mktmpfile(0, sb);
121 else if (!REGULAR_FILE(dir) && !DIRECTORY(dir)) {
123 if ((input = open(file, OREAD)) == -1) {
124 panic(mflag ? 0: 2, "cannot open %s: %r\n", file);
127 file = mktmpfile(input, sb);
136 diff(char *f, char *t, int level)
138 char *fp, *tp, *p, fb[MAXPATHLEN+1], tb[MAXPATHLEN+1];
141 if ((fp = statfile(f, &fsb)) == 0)
143 if ((tp = statfile(t, &tsb)) == 0){
147 if (DIRECTORY(fsb) && DIRECTORY(tsb)) {
148 if (rflag || level == 0)
149 diffdir(fp, tp, level);
151 Bprint(&stdout, "Common subdirectories: %s and %s\n",
154 else if (REGULAR_FILE(fsb) && REGULAR_FILE(tsb))
157 if (REGULAR_FILE(fsb)) {
158 if ((p = utfrrune(f, '/')) == 0)
162 if (mkpathname(tb, tp, p) == 0)
166 if ((p = utfrrune(t, '/')) == 0)
170 if (mkpathname(fb, fp, p) == 0)
181 main(int argc, char *argv[])
187 Binit(&stdout, 1, OWRITE);
189 while (--argc && (*++argv)[0] == '-' && (*argv)[1]) {
190 for (p = *argv+1; *p; p++) {
225 panic(2, usage, progname);
226 if ((tsb = dirstat(argv[argc-1])) == nil)
227 panic(2, "can't stat %s\n", argv[argc-1]);
230 panic(2, usage, progname);
234 if ((fsb = dirstat(argv[0])) == nil)
235 panic(2, "can't stat %s\n", argv[0]);
236 if (DIRECTORY(fsb) && DIRECTORY(tsb))
241 for (i = 0; i < argc-1; i++)
242 diff(argv[i], argv[argc-1], 0);
247 static char noroom[] = "out of memory - try diff -h\n";
254 if ((p = malloc(n)) == 0)
260 erealloc(void *p, unsigned n)
264 if ((rp = realloc(p, n)) == 0)