1*fa28c6faSchristos /* $NetBSD: rcsdiff.c,v 1.2 2016/01/14 04:22:39 christos Exp $ */
27bdc2678Schristos
37bdc2678Schristos /* Compare RCS revisions. */
47bdc2678Schristos
57bdc2678Schristos /* Copyright 1982, 1988, 1989 Walter Tichy
67bdc2678Schristos Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert
77bdc2678Schristos Distributed under license by the Free Software Foundation, Inc.
87bdc2678Schristos
97bdc2678Schristos This file is part of RCS.
107bdc2678Schristos
117bdc2678Schristos RCS is free software; you can redistribute it and/or modify
127bdc2678Schristos it under the terms of the GNU General Public License as published by
137bdc2678Schristos the Free Software Foundation; either version 2, or (at your option)
147bdc2678Schristos any later version.
157bdc2678Schristos
167bdc2678Schristos RCS is distributed in the hope that it will be useful,
177bdc2678Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of
187bdc2678Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
197bdc2678Schristos GNU General Public License for more details.
207bdc2678Schristos
217bdc2678Schristos You should have received a copy of the GNU General Public License
227bdc2678Schristos along with RCS; see the file COPYING.
237bdc2678Schristos If not, write to the Free Software Foundation,
247bdc2678Schristos 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
257bdc2678Schristos
267bdc2678Schristos Report problems and direct all questions to:
277bdc2678Schristos
287bdc2678Schristos rcs-bugs@cs.purdue.edu
297bdc2678Schristos
307bdc2678Schristos */
317bdc2678Schristos
327bdc2678Schristos /*
337bdc2678Schristos * Log: rcsdiff.c,v
347bdc2678Schristos * Revision 5.19 1995/06/16 06:19:24 eggert
357bdc2678Schristos * Update FSF address.
367bdc2678Schristos *
377bdc2678Schristos * Revision 5.18 1995/06/01 16:23:43 eggert
387bdc2678Schristos * (main): Pass "--binary" if -kb and if --binary makes a difference.
397bdc2678Schristos * Don't treat + options specially.
407bdc2678Schristos *
417bdc2678Schristos * Revision 5.17 1994/03/17 14:05:48 eggert
427bdc2678Schristos * Specify subprocess input via file descriptor, not file name. Remove lint.
437bdc2678Schristos *
447bdc2678Schristos * Revision 5.16 1993/11/09 17:40:15 eggert
457bdc2678Schristos * -V now prints version on stdout and exits. Don't print usage twice.
467bdc2678Schristos *
477bdc2678Schristos * Revision 5.15 1993/11/03 17:42:27 eggert
487bdc2678Schristos * Add -z. Ignore -T. Pass -Vn to `co'. Add Name keyword.
497bdc2678Schristos * Put revision numbers in -c output. Improve quality of diagnostics.
507bdc2678Schristos *
517bdc2678Schristos * Revision 5.14 1992/07/28 16:12:44 eggert
527bdc2678Schristos * Add -V. Use co -M for better dates with traditional diff -c.
537bdc2678Schristos *
547bdc2678Schristos * Revision 5.13 1992/02/17 23:02:23 eggert
557bdc2678Schristos * Output more readable context diff headers.
567bdc2678Schristos * Suppress needless checkout and comparison of identical revisions.
577bdc2678Schristos *
587bdc2678Schristos * Revision 5.12 1992/01/24 18:44:19 eggert
597bdc2678Schristos * Add GNU diff 1.15.2's new options. lint -> RCS_lint
607bdc2678Schristos *
617bdc2678Schristos * Revision 5.11 1992/01/06 02:42:34 eggert
627bdc2678Schristos * Update usage string.
637bdc2678Schristos *
647bdc2678Schristos * Revision 5.10 1991/10/07 17:32:46 eggert
657bdc2678Schristos * Remove lint.
667bdc2678Schristos *
677bdc2678Schristos * Revision 5.9 1991/08/19 03:13:55 eggert
687bdc2678Schristos * Add RCSINIT, -r$. Tune.
697bdc2678Schristos *
707bdc2678Schristos * Revision 5.8 1991/04/21 11:58:21 eggert
717bdc2678Schristos * Add -x, RCSINIT, MS-DOS support.
727bdc2678Schristos *
737bdc2678Schristos * Revision 5.7 1990/12/13 06:54:07 eggert
747bdc2678Schristos * GNU diff 1.15 has -u.
757bdc2678Schristos *
767bdc2678Schristos * Revision 5.6 1990/11/01 05:03:39 eggert
777bdc2678Schristos * Remove unneeded setid check.
787bdc2678Schristos *
797bdc2678Schristos * Revision 5.5 1990/10/04 06:30:19 eggert
807bdc2678Schristos * Accumulate exit status across files.
817bdc2678Schristos *
827bdc2678Schristos * Revision 5.4 1990/09/27 01:31:43 eggert
837bdc2678Schristos * Yield 1, not EXIT_FAILURE, when diffs are found.
847bdc2678Schristos *
857bdc2678Schristos * Revision 5.3 1990/09/11 02:41:11 eggert
867bdc2678Schristos * Simplify -kkvl test.
877bdc2678Schristos *
887bdc2678Schristos * Revision 5.2 1990/09/04 17:07:19 eggert
897bdc2678Schristos * Diff's argv was too small by 1.
907bdc2678Schristos *
917bdc2678Schristos * Revision 5.1 1990/08/29 07:13:55 eggert
927bdc2678Schristos * Add -kkvl.
937bdc2678Schristos *
947bdc2678Schristos * Revision 5.0 1990/08/22 08:12:46 eggert
957bdc2678Schristos * Add -k, -V. Don't use access(). Add setuid support.
967bdc2678Schristos * Remove compile-time limits; use malloc instead.
977bdc2678Schristos * Don't pass arguments with leading '+' to diff; GNU DIFF treats them as options.
987bdc2678Schristos * Add GNU diff's flags. Make lock and temp files faster and safer.
997bdc2678Schristos * Ansify and Posixate.
1007bdc2678Schristos *
1017bdc2678Schristos * Revision 4.6 89/05/01 15:12:27 narten
1027bdc2678Schristos * changed copyright header to reflect current distribution rules
1037bdc2678Schristos *
1047bdc2678Schristos * Revision 4.5 88/08/09 19:12:41 eggert
1057bdc2678Schristos * Use execv(), not system(); yield exit status like diff(1)s; allow cc -R.
1067bdc2678Schristos *
1077bdc2678Schristos * Revision 4.4 87/12/18 11:37:46 narten
1087bdc2678Schristos * changes Jay Lepreau made in the 4.3 BSD version, to add support for
1097bdc2678Schristos * "-i", "-w", and "-t" flags and to permit flags to be bundled together,
1107bdc2678Schristos * merged in.
1117bdc2678Schristos *
1127bdc2678Schristos * Revision 4.3 87/10/18 10:31:42 narten
1137bdc2678Schristos * Updating version numbers. Changes relative to 1.1 actually
1147bdc2678Schristos * relative to 4.1
1157bdc2678Schristos *
1167bdc2678Schristos * Revision 1.3 87/09/24 13:59:21 narten
1177bdc2678Schristos * Sources now pass through lint (if you ignore printf/sprintf/fprintf
1187bdc2678Schristos * warnings)
1197bdc2678Schristos *
1207bdc2678Schristos * Revision 1.2 87/03/27 14:22:15 jenkins
1217bdc2678Schristos * Port to suns
1227bdc2678Schristos *
1237bdc2678Schristos * Revision 4.1 83/05/03 22:13:19 wft
1247bdc2678Schristos * Added default branch, option -q, exit status like diff.
1257bdc2678Schristos * Added fterror() to replace faterror().
1267bdc2678Schristos *
1277bdc2678Schristos * Revision 3.6 83/01/15 17:52:40 wft
1287bdc2678Schristos * Expanded mainprogram to handle multiple RCS files.
1297bdc2678Schristos *
1307bdc2678Schristos * Revision 3.5 83/01/06 09:33:45 wft
1317bdc2678Schristos * Fixed passing of -c (context) option to diff.
1327bdc2678Schristos *
1337bdc2678Schristos * Revision 3.4 82/12/24 15:28:38 wft
1347bdc2678Schristos * Added call to catchsig().
1357bdc2678Schristos *
1367bdc2678Schristos * Revision 3.3 82/12/10 16:08:17 wft
1377bdc2678Schristos * Corrected checking of return code from diff; improved error msgs.
1387bdc2678Schristos *
1397bdc2678Schristos * Revision 3.2 82/12/04 13:20:09 wft
1407bdc2678Schristos * replaced getdelta() with gettree(). Changed diagnostics.
1417bdc2678Schristos *
1427bdc2678Schristos * Revision 3.1 82/11/28 19:25:04 wft
1437bdc2678Schristos * Initial revision.
1447bdc2678Schristos *
1457bdc2678Schristos */
1467bdc2678Schristos #include "rcsbase.h"
1477bdc2678Schristos
1487bdc2678Schristos #if DIFF_L
1497bdc2678Schristos static char const *setup_label P((struct buf*,char const*,char const[datesize]));
1507bdc2678Schristos #endif
1517bdc2678Schristos static void cleanup P((void));
1527bdc2678Schristos
1537bdc2678Schristos static int exitstatus;
1547bdc2678Schristos static RILE *workptr;
1557bdc2678Schristos static struct stat workstat;
1567bdc2678Schristos
1577bdc2678Schristos mainProg(rcsdiffId, "rcsdiff", "Id: rcsdiff.c,v 5.19 1995/06/16 06:19:24 eggert Exp ")
1587bdc2678Schristos {
1597bdc2678Schristos static char const cmdusage[] =
1607bdc2678Schristos "\nrcsdiff usage: rcsdiff -ksubst -q -rrev1 [-rrev2] -Vn -xsuff -zzone [diff options] file ...";
1617bdc2678Schristos
1627bdc2678Schristos int revnums; /* counter for revision numbers given */
1637bdc2678Schristos char const *rev1, *rev2; /* revision numbers from command line */
1647bdc2678Schristos char const *xrev1, *xrev2; /* expanded revision numbers */
1657bdc2678Schristos char const *expandarg, *lexpandarg, *suffixarg, *versionarg, *zonearg;
1667bdc2678Schristos #if DIFF_L
1677bdc2678Schristos static struct buf labelbuf[2];
1687bdc2678Schristos int file_labels;
1697bdc2678Schristos char const **diff_label1, **diff_label2;
1707bdc2678Schristos char date2[datesize];
1717bdc2678Schristos #endif
1727bdc2678Schristos char const *cov[10 + !DIFF_L];
1737bdc2678Schristos char const **diffv, **diffp, **diffpend; /* argv for subsidiary diff */
1747bdc2678Schristos char const **pp, *p, *diffvstr;
1757bdc2678Schristos struct buf commarg;
1767bdc2678Schristos struct buf numericrev; /* expanded revision number */
1777bdc2678Schristos struct hshentries *gendeltas; /* deltas to be generated */
1787bdc2678Schristos struct hshentry * target;
1797bdc2678Schristos char *a, *dcp, **newargv;
1807bdc2678Schristos int no_diff_means_no_output;
181*fa28c6faSchristos int c;
1827bdc2678Schristos
1837bdc2678Schristos exitstatus = DIFF_SUCCESS;
1847bdc2678Schristos
1857bdc2678Schristos bufautobegin(&commarg);
1867bdc2678Schristos bufautobegin(&numericrev);
1877bdc2678Schristos revnums = 0;
1887bdc2678Schristos rev1 = rev2 = xrev2 = 0;
1897bdc2678Schristos #if DIFF_L
1907bdc2678Schristos file_labels = 0;
1917bdc2678Schristos #endif
1927bdc2678Schristos expandarg = suffixarg = versionarg = zonearg = 0;
1937bdc2678Schristos no_diff_means_no_output = true;
1947bdc2678Schristos suffixes = X_DEFAULT;
1957bdc2678Schristos
1967bdc2678Schristos /*
1977bdc2678Schristos * Room for runv extra + args [+ --binary] [+ 2 labels]
1987bdc2678Schristos * + 1 file + 1 trailing null.
1997bdc2678Schristos */
2007bdc2678Schristos diffv = tnalloc(char const*, 1 + argc + !!OPEN_O_BINARY + 2*DIFF_L + 2);
2017bdc2678Schristos diffp = diffv + 1;
2027bdc2678Schristos *diffp++ = DIFF;
2037bdc2678Schristos
2047bdc2678Schristos argc = getRCSINIT(argc, argv, &newargv);
2057bdc2678Schristos argv = newargv;
2067bdc2678Schristos while (a = *++argv, 0<--argc && *a++=='-') {
2077bdc2678Schristos dcp = a;
2087bdc2678Schristos while ((c = *a++)) switch (c) {
2097bdc2678Schristos case 'r':
2107bdc2678Schristos switch (++revnums) {
2117bdc2678Schristos case 1: rev1=a; break;
2127bdc2678Schristos case 2: rev2=a; break;
2137bdc2678Schristos default: error("too many revision numbers");
2147bdc2678Schristos }
2157bdc2678Schristos goto option_handled;
2167bdc2678Schristos case '-': case 'D':
2177bdc2678Schristos no_diff_means_no_output = false;
2187bdc2678Schristos /* fall into */
219*fa28c6faSchristos case 'C': case 'F': case 'I': case 'L': case 'W': case 'U':
2207bdc2678Schristos #if DIFF_L
221*fa28c6faSchristos if (c == 'L' && file_labels++ == 2)
2227bdc2678Schristos faterror("too many -L options");
2237bdc2678Schristos #endif
2247bdc2678Schristos *dcp++ = c;
2257bdc2678Schristos if (*a)
2267bdc2678Schristos do *dcp++ = *a++;
2277bdc2678Schristos while (*a);
2287bdc2678Schristos else {
2297bdc2678Schristos if (!--argc)
2307bdc2678Schristos faterror("-%c needs following argument%s",
2317bdc2678Schristos c, cmdusage
2327bdc2678Schristos );
2337bdc2678Schristos *diffp++ = *argv++;
2347bdc2678Schristos }
2357bdc2678Schristos break;
2367bdc2678Schristos case 'y':
2377bdc2678Schristos no_diff_means_no_output = false;
2387bdc2678Schristos /* fall into */
2397bdc2678Schristos case 'B': case 'H':
2407bdc2678Schristos case '0': case '1': case '2': case '3': case '4':
2417bdc2678Schristos case '5': case '6': case '7': case '8': case '9':
2427bdc2678Schristos case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
2437bdc2678Schristos case 'h': case 'i': case 'n': case 'p':
2447bdc2678Schristos case 't': case 'u': case 'w':
2457bdc2678Schristos *dcp++ = c;
2467bdc2678Schristos break;
2477bdc2678Schristos case 'q':
2487bdc2678Schristos quietflag=true;
2497bdc2678Schristos break;
2507bdc2678Schristos case 'x':
2517bdc2678Schristos suffixarg = *argv;
2527bdc2678Schristos suffixes = *argv + 2;
2537bdc2678Schristos goto option_handled;
2547bdc2678Schristos case 'z':
2557bdc2678Schristos zonearg = *argv;
2567bdc2678Schristos zone_set(*argv + 2);
2577bdc2678Schristos goto option_handled;
2587bdc2678Schristos case 'T':
2597bdc2678Schristos /* Ignore -T, so that RCSINIT can contain -T. */
2607bdc2678Schristos if (*a)
2617bdc2678Schristos goto unknown;
2627bdc2678Schristos break;
2637bdc2678Schristos case 'V':
2647bdc2678Schristos versionarg = *argv;
2657bdc2678Schristos setRCSversion(versionarg);
2667bdc2678Schristos goto option_handled;
2677bdc2678Schristos case 'k':
2687bdc2678Schristos expandarg = *argv;
2697bdc2678Schristos if (0 <= str2expmode(expandarg+2))
2707bdc2678Schristos goto option_handled;
2717bdc2678Schristos /* fall into */
2727bdc2678Schristos default:
2737bdc2678Schristos unknown:
2747bdc2678Schristos error("unknown option: %s%s", *argv, cmdusage);
2757bdc2678Schristos };
2767bdc2678Schristos option_handled:
2777bdc2678Schristos if (dcp != *argv+1) {
2787bdc2678Schristos *dcp = 0;
2797bdc2678Schristos *diffp++ = *argv;
2807bdc2678Schristos }
2817bdc2678Schristos } /* end of option processing */
2827bdc2678Schristos
2837bdc2678Schristos for (pp = diffv+2, c = 0; pp<diffp; )
2847bdc2678Schristos c += strlen(*pp++) + 1;
2857bdc2678Schristos diffvstr = a = tnalloc(char, c + 1);
2867bdc2678Schristos for (pp = diffv+2; pp<diffp; ) {
2877bdc2678Schristos p = *pp++;
2887bdc2678Schristos *a++ = ' ';
2897bdc2678Schristos while ((*a = *p++))
2907bdc2678Schristos a++;
2917bdc2678Schristos }
2927bdc2678Schristos *a = 0;
2937bdc2678Schristos
2947bdc2678Schristos #if DIFF_L
2957bdc2678Schristos diff_label1 = diff_label2 = 0;
2967bdc2678Schristos if (file_labels < 2) {
2977bdc2678Schristos if (!file_labels)
2987bdc2678Schristos diff_label1 = diffp++;
2997bdc2678Schristos diff_label2 = diffp++;
3007bdc2678Schristos }
3017bdc2678Schristos #endif
3027bdc2678Schristos diffpend = diffp;
3037bdc2678Schristos
3047bdc2678Schristos cov[1] = CO;
3057bdc2678Schristos cov[2] = "-q";
3067bdc2678Schristos # if !DIFF_L
3077bdc2678Schristos cov[3] = "-M";
3087bdc2678Schristos # endif
3097bdc2678Schristos
3107bdc2678Schristos /* Now handle all pathnames. */
3117bdc2678Schristos if (nerror)
3127bdc2678Schristos cleanup();
3137bdc2678Schristos else if (argc < 1)
3147bdc2678Schristos faterror("no input file%s", cmdusage);
3157bdc2678Schristos else
3167bdc2678Schristos for (; 0 < argc; cleanup(), ++argv, --argc) {
3177bdc2678Schristos ffree();
3187bdc2678Schristos
3197bdc2678Schristos if (pairnames(argc, argv, rcsreadopen, true, false) <= 0)
3207bdc2678Schristos continue;
3217bdc2678Schristos diagnose("===================================================================\nRCS file: %s\n",RCSname);
3227bdc2678Schristos if (!rev2) {
3237bdc2678Schristos /* Make sure work file is readable, and get its status. */
3247bdc2678Schristos if (!(workptr = Iopen(workname, FOPEN_R_WORK, &workstat))) {
3257bdc2678Schristos eerror(workname);
3267bdc2678Schristos continue;
3277bdc2678Schristos }
3287bdc2678Schristos }
3297bdc2678Schristos
3307bdc2678Schristos
3317bdc2678Schristos gettree(); /* reads in the delta tree */
3327bdc2678Schristos
3337bdc2678Schristos if (!Head) {
3347bdc2678Schristos rcserror("no revisions present");
3357bdc2678Schristos continue;
3367bdc2678Schristos }
3377bdc2678Schristos if (revnums==0 || !*rev1)
3387bdc2678Schristos rev1 = Dbranch ? Dbranch : Head->num;
3397bdc2678Schristos
3407bdc2678Schristos if (!fexpandsym(rev1, &numericrev, workptr)) continue;
3417bdc2678Schristos if (!(target=genrevs(numericrev.string,(char *)0,(char *)0,(char *)0,&gendeltas))) continue;
3427bdc2678Schristos xrev1=target->num;
3437bdc2678Schristos #if DIFF_L
3447bdc2678Schristos if (diff_label1)
3457bdc2678Schristos *diff_label1 = setup_label(&labelbuf[0], target->num, target->date);
3467bdc2678Schristos #endif
3477bdc2678Schristos
3487bdc2678Schristos lexpandarg = expandarg;
3497bdc2678Schristos if (revnums==2) {
3507bdc2678Schristos if (!fexpandsym(
3517bdc2678Schristos *rev2 ? rev2 : Dbranch ? Dbranch : Head->num,
3527bdc2678Schristos &numericrev,
3537bdc2678Schristos workptr
3547bdc2678Schristos ))
3557bdc2678Schristos continue;
3567bdc2678Schristos if (!(target=genrevs(numericrev.string,(char *)0,(char *)0,(char *)0,&gendeltas))) continue;
3577bdc2678Schristos xrev2=target->num;
3587bdc2678Schristos if (no_diff_means_no_output && xrev1 == xrev2)
3597bdc2678Schristos continue;
3607bdc2678Schristos } else if (
3617bdc2678Schristos target->lockedby
3627bdc2678Schristos && !lexpandarg
3637bdc2678Schristos && Expand == KEYVAL_EXPAND
3647bdc2678Schristos && WORKMODE(RCSstat.st_mode,true) == workstat.st_mode
3657bdc2678Schristos )
3667bdc2678Schristos lexpandarg = "-kkvl";
3677bdc2678Schristos Izclose(&workptr);
3687bdc2678Schristos #if DIFF_L
369*fa28c6faSchristos if (diff_label2) {
3707bdc2678Schristos if (revnums == 2)
3717bdc2678Schristos *diff_label2 = setup_label(&labelbuf[1], target->num, target->date);
3727bdc2678Schristos else {
3737bdc2678Schristos time2date(workstat.st_mtime, date2);
3747bdc2678Schristos *diff_label2 = setup_label(&labelbuf[1], (char*)0, date2);
3757bdc2678Schristos }
376*fa28c6faSchristos }
3777bdc2678Schristos #endif
3787bdc2678Schristos
3797bdc2678Schristos diagnose("retrieving revision %s\n", xrev1);
3807bdc2678Schristos bufscpy(&commarg, "-p");
3817bdc2678Schristos bufscat(&commarg, rev1); /* not xrev1, for $Name's sake */
3827bdc2678Schristos
3837bdc2678Schristos pp = &cov[3 + !DIFF_L];
3847bdc2678Schristos *pp++ = commarg.string;
3857bdc2678Schristos if (lexpandarg) *pp++ = lexpandarg;
3867bdc2678Schristos if (suffixarg) *pp++ = suffixarg;
3877bdc2678Schristos if (versionarg) *pp++ = versionarg;
3887bdc2678Schristos if (zonearg) *pp++ = zonearg;
3897bdc2678Schristos *pp++ = RCSname;
3907bdc2678Schristos *pp = 0;
3917bdc2678Schristos
3927bdc2678Schristos diffp = diffpend;
3937bdc2678Schristos # if OPEN_O_BINARY
3947bdc2678Schristos if (Expand == BINARY_EXPAND)
3957bdc2678Schristos *diffp++ = "--binary";
3967bdc2678Schristos # endif
3977bdc2678Schristos diffp[0] = maketemp(0);
3987bdc2678Schristos if (runv(-1, diffp[0], cov)) {
3997bdc2678Schristos rcserror("co failed");
4007bdc2678Schristos continue;
4017bdc2678Schristos }
4027bdc2678Schristos if (!rev2) {
4037bdc2678Schristos diffp[1] = workname;
4047bdc2678Schristos if (*workname == '-') {
4057bdc2678Schristos char *dp = ftnalloc(char, strlen(workname)+3);
4067bdc2678Schristos diffp[1] = dp;
4077bdc2678Schristos *dp++ = '.';
4087bdc2678Schristos *dp++ = SLASH;
4097bdc2678Schristos VOID strcpy(dp, workname);
4107bdc2678Schristos }
4117bdc2678Schristos } else {
4127bdc2678Schristos diagnose("retrieving revision %s\n",xrev2);
4137bdc2678Schristos bufscpy(&commarg, "-p");
4147bdc2678Schristos bufscat(&commarg, rev2); /* not xrev2, for $Name's sake */
4157bdc2678Schristos cov[3 + !DIFF_L] = commarg.string;
4167bdc2678Schristos diffp[1] = maketemp(1);
4177bdc2678Schristos if (runv(-1, diffp[1], cov)) {
4187bdc2678Schristos rcserror("co failed");
4197bdc2678Schristos continue;
4207bdc2678Schristos }
4217bdc2678Schristos }
4227bdc2678Schristos if (!rev2)
4237bdc2678Schristos diagnose("diff%s -r%s %s\n", diffvstr, xrev1, workname);
4247bdc2678Schristos else
4257bdc2678Schristos diagnose("diff%s -r%s -r%s\n", diffvstr, xrev1, xrev2);
4267bdc2678Schristos
4277bdc2678Schristos diffp[2] = 0;
4287bdc2678Schristos switch (runv(-1, (char*)0, diffv)) {
4297bdc2678Schristos case DIFF_SUCCESS:
4307bdc2678Schristos break;
4317bdc2678Schristos case DIFF_FAILURE:
4327bdc2678Schristos if (exitstatus == DIFF_SUCCESS)
4337bdc2678Schristos exitstatus = DIFF_FAILURE;
4347bdc2678Schristos break;
4357bdc2678Schristos default:
4367bdc2678Schristos workerror("diff failed");
4377bdc2678Schristos }
4387bdc2678Schristos }
4397bdc2678Schristos
4407bdc2678Schristos tempunlink();
4417bdc2678Schristos exitmain(exitstatus);
4427bdc2678Schristos }
4437bdc2678Schristos
4447bdc2678Schristos static void
cleanup()4457bdc2678Schristos cleanup()
4467bdc2678Schristos {
4477bdc2678Schristos if (nerror) exitstatus = DIFF_TROUBLE;
4487bdc2678Schristos Izclose(&finptr);
4497bdc2678Schristos Izclose(&workptr);
4507bdc2678Schristos }
4517bdc2678Schristos
4527bdc2678Schristos #if RCS_lint
4537bdc2678Schristos # define exiterr rdiffExit
4547bdc2678Schristos #endif
4557bdc2678Schristos void
exiterr()4567bdc2678Schristos exiterr()
4577bdc2678Schristos {
4587bdc2678Schristos tempunlink();
4597bdc2678Schristos _exit(DIFF_TROUBLE);
4607bdc2678Schristos }
4617bdc2678Schristos
4627bdc2678Schristos #if DIFF_L
4637bdc2678Schristos static char const *
setup_label(b,num,date)4647bdc2678Schristos setup_label(b, num, date)
4657bdc2678Schristos struct buf *b;
4667bdc2678Schristos char const *num;
4677bdc2678Schristos char const date[datesize];
4687bdc2678Schristos {
4697bdc2678Schristos char *p;
4707bdc2678Schristos char datestr[datesize + zonelenmax];
4717bdc2678Schristos VOID date2str(date, datestr);
4727bdc2678Schristos bufalloc(b,
4737bdc2678Schristos strlen(workname)
4747bdc2678Schristos + sizeof datestr + 4
4757bdc2678Schristos + (num ? strlen(num) : 0)
4767bdc2678Schristos );
4777bdc2678Schristos p = b->string;
4787bdc2678Schristos if (num)
4797bdc2678Schristos VOID sprintf(p, "-L%s\t%s\t%s", workname, datestr, num);
4807bdc2678Schristos else
4817bdc2678Schristos VOID sprintf(p, "-L%s\t%s", workname, datestr);
4827bdc2678Schristos return p;
4837bdc2678Schristos }
4847bdc2678Schristos #endif
485