/* * Do the actual diff by calling either diffreg() or diffdir(). */ static void diffit(struct dirent *dp, char *path1, size_t plen1, char *path2, size_t plen2, int flags) { flags |= D_HEADER; strlcpy(path1 + plen1, dp->d_name, MAXPATHLEN - plen1); if (stat(path1, &stb1) != 0) { if (!(Nflag || Pflag) || errno != ENOENT) { warn("%s", path1); return; } flags |= D_EMPTY1; memset(&stb1, 0, sizeof(stb1)); } strlcpy(path2 + plen2, dp->d_name, MAXPATHLEN - plen2); if (stat(path2, &stb2) != 0) { if (!Nflag || errno != ENOENT) { warn("%s", path2); return; } flags |= D_EMPTY2; memset(&stb2, 0, sizeof(stb2)); stb2.st_mode = stb1.st_mode; } if (stb1.st_mode == 0) stb1.st_mode = stb2.st_mode; if (S_ISDIR(stb1.st_mode) && S_ISDIR(stb2.st_mode)) { if (rflag) diffdir(path1, path2, flags); else if (lflag) dp->d_status |= D_COMMON; else printf("Common subdirectories: %s and %s\n", path1, path2); return; } if (!S_ISREG(stb1.st_mode) && !S_ISDIR(stb1.st_mode)) dp->d_status = D_SKIPPED1; else if (!S_ISREG(stb2.st_mode) && !S_ISDIR(stb2.st_mode)) dp->d_status = D_SKIPPED2; else dp->d_status = diffreg(path1, path2, flags); if (!lflag) print_status(dp->d_status, path1, path2, ""); }
void pseudomain(int argc, char **argv, FILE *file) { buffer = file; char *ep, **oargv, *optfile; const char *pn; long l; int ch, lastch, gotstdin, prevoptind, newarg; // int oargc; filebehave = FILE_NORMAL; /* Check what is the program name of the binary. In this way we can have all the funcionalities in one binary without the need of scripting and using ugly hacks. */ pn = getprogname(); if (pn[0] == 'z') { filebehave = FILE_GZIP; } oargv = argv; // oargc = argc; gotstdin = 0; optfile = "\0"; lastch = '\0'; prevoptind = 1; newarg = 1; while ((ch = getopt_long(argc, argv, OPTIONS, longopts, NULL)) != -1) { switch (ch) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (newarg) usage(); /* disallow -[0-9]+ */ else if (lastch == 'c' || lastch == 'u') context = 0; else if (!isdigit(lastch) || context > INT_MAX / 10) usage(); context = (context * 10) + (ch - '0'); break; case 'a': aflag = 1; break; case 'b': bflag = 1; break; case 'B': Bflag = 1; break; case 'C': case 'c': cflag = 1; format = D_CONTEXT; if (optarg != NULL) { l = strtol(optarg, &ep, 10); if (*ep != '\0' || l < 0 || l >= INT_MAX) usage(); context = (int)l; } else context = 3; break; case 'D': format = D_IFDEF; ifdefname = optarg; break; case 'd': dflag = 1; break; case 'E': Eflag = 1; break; case 'e': format = D_EDIT; break; case 'f': format = D_REVERSE; break; case 'h': /* silently ignore for backwards compatibility */ break; case 'I': push_ignore_pats(optarg); break; case 'i': iflag = 1; break; case 'L': if (label[0] == NULL) label[0] = optarg; else if (label[1] == NULL) label[1] = optarg; else usage(); break; case 'l': lflag = 1; signal(SIGPIPE, SIG_IGN); break; case 'N': Nflag = 1; break; case 'n': format = D_NREVERSE; break; case 'P': Pflag = 1; break; case 'p': pflag = 1; break; case 'r': rflag = 1; break; case 'q': format = D_BRIEF; break; case 'S': start = optarg; break; case 's': sflag = 1; break; case 'T': Tflag = 1; break; case 't': tflag = 1; break; case 'U': case 'u': format = D_UNIFIED; if (optarg != NULL) { l = strtol(optarg, &ep, 10); if (*ep != '\0' || l < 0 || l >= INT_MAX) usage(); context = (int)l; } else context = 3; break; case 'v': fprintf(buffer, "FreeBSD diff 2.8.7\n"); exit(0); case 'W': wflag = 1; break; case 'X': read_excludes_file(optarg); break; case 'x': push_excludes(optarg); break; case 'y': yflag = 1; break; case OPT_FFILE: Toflag = 1; optfile = optarg; break; case OPT_TOFILE: Fromflag = 1; optfile = optarg; break; case OPT_CHGD_GF: case OPT_NEW_GF: case OPT_OLD_GF: case OPT_UNCHGD_GF: /* XXX To do: Complete --GTYPE-group-format. */ format = D_GF; group_format = optarg; break; case OPT_NEW_LF: case OPT_OLD_LF: case OPT_UNCHGD_LF: case OPT_LF: /* XXX To do: Complete --line-format. */ format = D_LF; line_format = optarg; break; case OPT_NORMAL: format = D_NORMAL; break; case OPT_LEFTC: /* Do nothing, passes option to sdiff. */ break; case OPT_SUPCL: /* Do nothing, passes option to sdiff. */ break; case OPT_TSIZE: if (optarg != NULL) { l = strtol(optarg, &ep, 10); if (*ep != '\0' || l < 1 || l >= INT_MAX) usage(); tabsize = (int)l; } else tabsize = 8; break; case OPT_STRIPCR: strip_cr=1; break; case OPT_IGN_FN_CASE: ignore_file_case = 1; break; case OPT_NIGN_FN_CASE: ignore_file_case = 0; break; case OPT_HELP: for (; *help_strs; help_strs++) { fprintf(buffer, "%s\n", *help_strs); } exit(0); break; default: usage(); break; } lastch = ch; newarg = optind != prevoptind; prevoptind = optind; } argc -= optind; argv += optind; // if (yflag) { // /* remove y flag from args and call sdiff */ // for (argv = oargv; argv && strcmp(*argv, "-y") != 0 && // strcmp(*argv, "--side-by-side") != 0; argv++); // while(argv != &oargv[oargc]){ // *argv= *(argv+1); // argv++; // } // oargv[0] = _PATH_SDIFF; // *argv= "\0"; // execv(_PATH_SDIFF, oargv); // _exit(1); // } /* * Do sanity checks, fill in stb1 and stb2 and call the appropriate * driver routine. Both drivers use the contents of stb1 and stb2. */ if (argc != 2) usage(); if (ignore_pats != NULL) { char buf[BUFSIZ]; int error; if ((error = regcomp(&ignore_re, ignore_pats, REG_NEWLINE | REG_EXTENDED)) != 0) { regerror(error, &ignore_re, buf, sizeof(buf)); if (*ignore_pats != '\0') errx(2, "%s: %s", ignore_pats, buf); else errx(2, "%s", buf); } } if (strcmp(argv[0], "-") == 0) { fstat(STDIN_FILENO, &stb1); gotstdin = 1; } else if (stat(argv[0], &stb1) != 0) err(2, "%s", argv[0]); if (strcmp(argv[1], "-") == 0) { fstat(STDIN_FILENO, &stb2); gotstdin = 1; } else if (stat(argv[1], &stb2) != 0) err(2, "%s", argv[1]); if (gotstdin && (S_ISDIR(stb1.st_mode) || S_ISDIR(stb2.st_mode))) errx(2, "can't compare - to a directory"); set_argstr(oargv, argv); if (S_ISDIR(stb1.st_mode) && S_ISDIR(stb2.st_mode)) { if (format == D_IFDEF) if (ch == 'D') errx(2, "-D option not supported with directories"); if (ch == OPT_LF) errx(2, "--line-format option not supported with directories"); diffdir(argv[0], argv[1]); } else { if (S_ISDIR(stb1.st_mode)) { argv[0] = splice(argv[0], argv[1]); if (stat(argv[0], &stb1) < 0) err(2, "%s", argv[0]); } if (S_ISDIR(stb2.st_mode)) { argv[1] = splice(argv[1], argv[0]); if (stat(argv[1], &stb2) < 0) err(2, "%s", argv[1]); } /* Checks if --to-file or --from-file are specified */ if (Toflag && Fromflag) { (void)fprintf(stderr, "--from-file and --to-file both specified.\n"); exit(1); } if (Toflag) { print_status(diffreg(optfile, argv[0], 0), optfile, argv[0], NULL); print_status(diffreg(optfile, argv[1], 0), optfile, argv[1], NULL); } if (Fromflag) { print_status(diffreg(argv[0], optfile, 0), argv[0], optfile, NULL); print_status(diffreg(argv[1], optfile, 0), argv[1], optfile, NULL); } if (!Toflag && !Fromflag) print_status(diffreg(argv[0], argv[1], 0), argv[0], argv[1], NULL); } }