1: static  char *sccsid = "@(#)diffdir.c	4.5 (Berkeley) 81/02/28";
   2: 
   3: #include "diff.h"
   4: /*
   5:  * diff - directory comparison
   6:  */
   7: #define d_flags d_ino
   8: 
   9: #define ONLY    1       /* Only in this directory */
  10: #define SAME    2       /* Both places and same */
  11: #define DIFFER  4       /* Both places and different */
  12: #define DIRECT  8       /* Directory */
  13: 
  14: struct  direct *setupdir();
  15: int header;
  16: char    title[2*BUFSIZ], *etitle;
  17: 
  18: diffdir(argv)
  19:     char **argv;
  20: {
  21:     register struct direct *d1, *d2;
  22:     struct direct *dir1, *dir2;
  23:     register int i;
  24:     int cmp;
  25: 
  26:     if (opt == D_IFDEF) {
  27:         fprintf(stderr, "diff: can't specify -I with directories\n");
  28:         done();
  29:     }
  30:     if (opt == D_EDIT && (sflag || lflag))
  31:         fprintf(stderr,
  32:             "diff: warning: shouldn't give -s or -l with -e\n");
  33:     title[0] = 0;
  34:     strcpy(title, "diff ");
  35:     for (i = 1; diffargv[i+2]; i++) {
  36:         if (!strcmp(diffargv[i], "-"))
  37:             continue;   /* was -S, dont look silly */
  38:         strcat(title, diffargv[i]);
  39:         strcat(title, " ");
  40:     }
  41:     for (etitle = title; *etitle; etitle++)
  42:         ;
  43:     setfile(&file1, &efile1, file1);
  44:     setfile(&file2, &efile2, file2);
  45:     argv[0] = file1;
  46:     argv[1] = file2;
  47:     dir1 = setupdir(file1);
  48:     dir2 = setupdir(file2);
  49:     d1 = dir1; d2 = dir2;
  50:     while (d1->d_name[0] != 0 || d2->d_name[0] != 0) {
  51:         if (d1->d_name[0] && useless(d1->d_name)) {
  52:             d1++;
  53:             continue;
  54:         }
  55:         if (d2->d_name[0] && useless(d2->d_name)) {
  56:             d2++;
  57:             continue;
  58:         }
  59:         if (d1->d_name[0] == 0)
  60:             cmp = 1;
  61:         else if (d2->d_name[0] == 0)
  62:             cmp = -1;
  63:         else
  64:             cmp = strncmp(d1->d_name, d2->d_name, DIRSIZ);
  65:         if (cmp < 0) {
  66:             if (lflag)
  67:                 d1->d_flags |= ONLY;
  68:             else if (opt == 0 || opt == 2) {
  69:                 only(d1, 1);
  70:                 printf(": %.*s\n", DIRSIZ, d1->d_name);
  71:             }
  72:             d1++;
  73:         } else if (cmp == 0) {
  74:             compare(d1);
  75:             d1++;
  76:             d2++;
  77:         } else {
  78:             if (lflag)
  79:                 d2->d_flags |= ONLY;
  80:             else if (opt == 0 || opt == 2) {
  81:                 only(d2, 2);
  82:                 printf(": %.*s\n", DIRSIZ, d2->d_name);
  83:             }
  84:             d2++;
  85:         }
  86:     }
  87:     if (lflag) {
  88:         scanpr(dir1, ONLY, "Only in %.*s", file1, efile1);
  89:         scanpr(dir2, ONLY, "Only in %.*s", file2, efile2);
  90:         scanpr(dir1, SAME, "Common identical files", 0, 0);
  91:         scanpr(dir1, DIFFER, "Binary files which differ", 0, 0);
  92:         scanpr(dir1, DIRECT, "Common subdirectories", 0, 0);
  93:     }
  94:     if (rflag) {
  95:         if (header && lflag)
  96:             printf("\f");
  97:         for (d1 = dir1; d1->d_name[0]; d1++)  {
  98:             if ((d1->d_flags & DIRECT) == 0)
  99:                 continue;
 100:             strncpy(efile1, d1->d_name, DIRSIZ);
 101:             strncpy(efile2, d1->d_name, DIRSIZ);
 102: /*
 103: 			if (opt != D_EDIT) {
 104: 				*etitle = 0;
 105: 				printf("%s%s %s\n", title, file1, file2);
 106: 			}
 107: */
 108:             calldiff(0);
 109:         }
 110:     }
 111: }
 112: 
 113: setfile(fpp, epp, file)
 114:     char **fpp, **epp;
 115:     char *file;
 116: {
 117:     register char *cp;
 118: 
 119:     *fpp = malloc(BUFSIZ);
 120:     if (*fpp == 0) {
 121:         fprintf(stderr, "diff: ran out of memory\n");
 122:         exit(1);
 123:     }
 124:     strcpy(*fpp, file);
 125:     for (cp = *fpp; *cp; cp++)
 126:         continue;
 127:     *cp++ = '/';
 128:     *epp = cp;
 129: }
 130: 
 131: scanpr(dp, test, title, file, efile)
 132:     register struct direct *dp;
 133:     int test;
 134:     char *title, *file, *efile;
 135: {
 136:     int titled = 0;
 137: 
 138:     for (; dp->d_name[0]; dp++)
 139:         if (dp->d_flags & test) {
 140:             if (titled == 0) {
 141:                 if (header == 0) {
 142:                     if (anychange)
 143:                         printf("\f");
 144:                     header = 1;
 145:                 } else
 146:                     printf("\n");
 147:                 printf(title, efile - file - 1, file);
 148:                 printf(":\n");
 149:                 titled = 1;
 150:             }
 151:             ptname(dp);
 152:         }
 153: }
 154: 
 155: only(dp, which)
 156:     struct direct *dp;
 157:     int which;
 158: {
 159:     char *file = which == 1 ? file1 : file2;
 160:     char *efile = which == 1 ? efile1 : efile2;
 161: 
 162:     printf("Only in %.*s", efile - file - 1, file, DIRSIZ, dp->d_name);
 163: }
 164: 
 165: ptname(dp)
 166:     struct direct *dp;
 167: {
 168: 
 169:     printf("\t%.*s\n", DIRSIZ, dp->d_name);
 170: }
 171: 
 172: int entcmp();
 173: 
 174: struct direct *
 175: setupdir(cp)
 176:     char *cp;
 177: {
 178:     struct stat stb;
 179:     register struct direct *dp, *ep;
 180: 
 181:     close(0);
 182:     if (open(cp, 0) < 0) {
 183:         fprintf(stderr, "diff: ");
 184:         perror(cp);
 185:         done();
 186:     }
 187:     fstat(0, &stb);
 188:     dp = (struct direct *)malloc((unsigned) stb.st_size + sizeof (struct direct));
 189:     if (dp == 0) {
 190:         fprintf(stderr, "diff: ran out of memory\n");
 191:         done();
 192:     }
 193:     if (read(0, (char *)dp, (int)stb.st_size) != (int)stb.st_size) {
 194:         fprintf(stderr, "diff: ");
 195:         perror(cp);
 196:         done();
 197:     }
 198:     qsort(dp, (int) stb.st_size / sizeof (struct direct),
 199:         sizeof (struct direct), entcmp);
 200:     ep = &dp[stb.st_size / sizeof (struct direct)];
 201:     ep->d_name[0] = 0;
 202:     while (--ep >= dp && ep->d_ino == 0)
 203:         ep->d_name[0] = 0;
 204:     for (; ep >= dp; ep--)
 205:         ep->d_flags = 0;
 206:     return (dp);
 207: }
 208: 
 209: entcmp(d1, d2)
 210:     struct direct *d1, *d2;
 211: {
 212: 
 213:     if (d1->d_ino == 0)
 214:         return (1);
 215:     if (d2->d_ino == 0)
 216:         return (-1);
 217:     return (strncmp(d1->d_name, d2->d_name, DIRSIZ));
 218: }
 219: 
 220: compare(dp)
 221:     register struct direct *dp;
 222: {
 223:     register int i, j;
 224:     int f1, f2, fmt1, fmt2;
 225:     struct stat stb1, stb2;
 226:     int flag = 0;
 227:     char buf1[BUFSIZ], buf2[BUFSIZ];
 228: 
 229:     strncpy(efile1, dp->d_name, DIRSIZ);
 230:     strncpy(efile2, dp->d_name, DIRSIZ);
 231:     f1 = open(file1, 0);
 232:     if (f1 < 0) {
 233:         perror(file1);
 234:         return;
 235:     }
 236:     f2 = open(file2, 0);
 237:     if (f2 < 0) {
 238:         perror(file2);
 239:         close(f1);
 240:         return;
 241:     }
 242:     fstat(f1, &stb1); fstat(f2, &stb2);
 243:     fmt1 = stb1.st_mode & S_IFMT;
 244:     fmt2 = stb2.st_mode & S_IFMT;
 245:     if (fmt1 != S_IFREG || fmt2 != S_IFREG) {
 246:         if (fmt1 == fmt2) {
 247:             if (fmt1 != S_IFDIR && stb1.st_rdev == stb2.st_rdev)
 248:                 goto same;
 249:             if (fmt1 == S_IFDIR) {
 250:                 dp->d_flags = DIRECT;
 251:                 if (lflag || opt == D_EDIT)
 252:                     goto closem;
 253:                 printf("Common subdirectories: %s and %s\n",
 254:                     file1, file2);
 255:                 goto closem;
 256:             }
 257:         }
 258:         goto notsame;
 259:     }
 260:     if (stb1.st_size != stb2.st_size)
 261:         goto notsame;
 262:     for (;;) {
 263:         i = read(f1, buf1, BUFSIZ);
 264:         j = read(f2, buf2, BUFSIZ);
 265:         if (i < 0 || j < 0 || i != j)
 266:             goto notsame;
 267:         if (i == 0 && j == 0)
 268:             goto same;
 269:         for (j = 0; j < i; j++)
 270:             if (buf1[j] != buf2[j])
 271:                 goto notsame;
 272:     }
 273: same:
 274:     if (sflag == 0)
 275:         goto closem;
 276:     if (lflag)
 277:         dp->d_flags = SAME;
 278:     else
 279:         printf("Files %s and %s are identical\n", file1, file2);
 280:     goto closem;
 281: notsame:
 282:     if (!ascii(f1) || !ascii(f2)) {
 283:         if (lflag)
 284:             dp->d_flags |= DIFFER;
 285:         else if (opt == D_NORMAL || opt == D_CONTEXT)
 286:             printf("Binary files %s and %s differ\n",
 287:                 file1, file2);
 288:         goto closem;
 289:     }
 290:     close(f1); close(f2);
 291:     anychange = 1;
 292:     if (lflag)
 293:         calldiff(title);
 294:     else {
 295:         if (opt == D_EDIT) {
 296:             printf("ed - %.*s << '-*-END-*-'\n",
 297:                 DIRSIZ, dp->d_name);
 298:             calldiff(0);
 299:         } else {
 300:             printf("%s%s %s\n", title, file1, file2);
 301:             calldiff(0);
 302:         }
 303:         if (opt == D_EDIT)
 304:             printf("w\nq\n-*-END-*-\n");
 305:     }
 306:     return;
 307: closem:
 308:     close(f1); close(f2);
 309: }
 310: 
 311: char    *prargs[] = { "pr", "-h", 0, "-f", 0, 0 };
 312: 
 313: calldiff(wantpr)
 314:     char *wantpr;
 315: {
 316:     int pid, status, status2, pv[2];
 317: 
 318:     prargs[2] = wantpr;
 319:     fflush(stdout);
 320:     if (wantpr) {
 321:         sprintf(etitle, "%s %s", file1, file2);
 322:         pipe(pv);
 323:         pid = fork();
 324:         if (pid == -1) {
 325:             fprintf(stderr, "No more processes");
 326:             done();
 327:         }
 328:         if (pid == 0) {
 329:             close(0);
 330:             dup(pv[0]);
 331:             close(pv[0]);
 332:             close(pv[1]);
 333:             execv(pr+4, prargs);
 334:             execv(pr, prargs);
 335:             perror(pr);
 336:             done();
 337:         }
 338:     }
 339:     pid = fork();
 340:     if (pid == -1) {
 341:         fprintf(stderr, "diff: No more processes\n");
 342:         done();
 343:     }
 344:     if (pid == 0) {
 345:         if (wantpr) {
 346:             close(1);
 347:             dup(pv[1]);
 348:             close(pv[0]);
 349:             close(pv[1]);
 350:         }
 351:         execv(diff+4, diffargv);
 352:         execv(diff, diffargv);
 353:         perror(diff);
 354:         done();
 355:     }
 356:     close(pv[0]);
 357:     close(pv[1]);
 358:     while (wait(&status) != pid)
 359:         continue;
 360:     while (wait(&status2) != -1)
 361:         continue;
 362: /*
 363: 	if ((status >> 8) >= 2)
 364: 		done();
 365: */
 366: }
 367: 
 368: #include <a.out.h>
 369: 
 370: ascii(f)
 371:     int f;
 372: {
 373:     char buf[BUFSIZ];
 374:     register int cnt;
 375:     register char *cp;
 376: 
 377:     lseek(f, (long)0, 0);
 378:     cnt = read(f, buf, BUFSIZ);
 379:     if (cnt >= sizeof (struct exec)) {
 380:         struct exec hdr;
 381:         hdr = *(struct exec *)buf;
 382:         if (!N_BADMAG(hdr))
 383:             return (0);
 384:     }
 385:     cp = buf;
 386:     while (--cnt >= 0)
 387:         if (*cp++ & 0200)
 388:             return (0);
 389:     return (1);
 390: }
 391: 
 392: /*
 393:  * THIS IS CRUDE.
 394:  */
 395: useless(cp)
 396: register char *cp;
 397: {
 398: 
 399:     if (cp[0] == '.')
 400:         return (1);
 401:     if (start && strcmp(start, cp) > 0)
 402:         return (1);
 403:     return (0);
 404: }

Defined functions

ascii defined in line 370; used 2 times
  • in line 282(2)
calldiff defined in line 313; used 4 times
compare defined in line 220; used 1 times
  • in line 74
diffdir defined in line 18; used 1 times
entcmp defined in line 209; used 2 times
only defined in line 155; used 2 times
ptname defined in line 165; used 1 times
scanpr defined in line 131; used 5 times
setfile defined in line 113; used 2 times
setupdir defined in line 174; used 3 times
useless defined in line 395; used 2 times

Defined variables

etitle defined in line 16; used 4 times
header defined in line 15; used 3 times
prargs defined in line 311; used 3 times
sccsid defined in line 1; never used
title defined in line 16; used 10 times

Defined macros

DIFFER defined in line 11; used 2 times
DIRECT defined in line 12; used 3 times
ONLY defined in line 9; used 4 times
SAME defined in line 10; used 2 times
d_flags defined in line 7; used 8 times
Last modified: 1981-03-01
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1628
Valid CSS Valid XHTML 1.0 Strict