xref: /openbsd-src/usr.bin/diff/diff.c (revision d0c3f5756de861fe4b7784c4a45fd032d25633c0)
1 /*	$OpenBSD: diff.c,v 1.2 2003/06/25 01:23:38 deraadt Exp $	*/
2 
3 /*
4  * Copyright (C) Caldera International Inc.  2001-2002.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code and documentation must retain the above
11  *    copyright notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *	This product includes software developed or owned by Caldera
18  *	International, Inc.
19  * 4. Neither the name of Caldera International, Inc. nor the names of other
20  *    contributors may be used to endorse or promote products derived from
21  *    this software without specific prior written permission.
22  *
23  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
24  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
25  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27  * IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE FOR ANY DIRECT,
28  * INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
32  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
33  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34  * POSSIBILITY OF SUCH DAMAGE.
35  */
36 
37 static	char sccsid[] = "@(#)diff.c 4.7 5/11/89";
38 
39 #include "diff.h"
40 #include "pathnames.h"
41 
42 /*
43  * diff - driver and subroutines
44  */
45 
46 char	diff[] = _PATH_DIFF;
47 char	diffh[] = _PATH_DIFFH;
48 char	pr[] = _PATH_PR;
49 
50 main(argc, argv)
51 	int argc;
52 	char **argv;
53 {
54 	register char *argp;
55 
56 	ifdef1 = "FILE1"; ifdef2 = "FILE2";
57 	status = 2;
58 	diffargv = argv;
59 	argc--, argv++;
60 	while (argc > 2 && argv[0][0] == '-') {
61 		argp = &argv[0][1];
62 		argv++, argc--;
63 		while (*argp) switch(*argp++) {
64 
65 #ifdef notdef
66 		case 'I':
67 			opt = D_IFDEF;
68 			wantelses = 0;
69 			continue;
70 		case 'E':
71 			opt = D_IFDEF;
72 			wantelses = 1;
73 			continue;
74 		case '1':
75 			opt = D_IFDEF;
76 			ifdef1 = argp;
77 			*--argp = 0;
78 			continue;
79 #endif
80 		case 'D':
81 			/* -Dfoo = -E -1 -2foo */
82 			wantelses = 1;
83 			ifdef1 = "";
84 			/* fall through */
85 #ifdef notdef
86 		case '2':
87 #endif
88 			opt = D_IFDEF;
89 			ifdef2 = argp;
90 			*--argp = 0;
91 			continue;
92 		case 'e':
93 			opt = D_EDIT;
94 			continue;
95 		case 'f':
96 			opt = D_REVERSE;
97 			continue;
98 		case 'n':
99 			opt = D_NREVERSE;
100 			continue;
101 		case 'b':
102 			bflag = 1;
103 			continue;
104 		case 'w':
105 			wflag = 1;
106 			continue;
107 		case 'i':
108 			iflag = 1;
109 			continue;
110 		case 't':
111 			tflag = 1;
112 			continue;
113 		case 'c':
114 			opt = D_CONTEXT;
115 			if (isdigit(*argp)) {
116 				context = atoi(argp);
117 				while (isdigit(*argp))
118 					argp++;
119 				if (*argp) {
120 					fprintf(stderr,
121 					    "diff: -c: bad count\n");
122 					done();
123 				}
124 				argp = "";
125 			} else
126 				context = 3;
127 			continue;
128 		case 'h':
129 			hflag++;
130 			continue;
131 		case 'S':
132 			if (*argp == 0) {
133 				fprintf(stderr, "diff: use -Sstart\n");
134 				done();
135 			}
136 			start = argp;
137 			*--argp = 0;		/* don't pass it on */
138 			continue;
139 		case 'r':
140 			rflag++;
141 			continue;
142 		case 's':
143 			sflag++;
144 			continue;
145 		case 'l':
146 			lflag++;
147 			continue;
148 		default:
149 			fprintf(stderr, "diff: -%s: unknown option\n",
150 			    --argp);
151 			done();
152 		}
153 	}
154 	if (argc != 2) {
155 		fprintf(stderr, "diff: two filename arguments required\n");
156 		done();
157 	}
158 	file1 = argv[0];
159 	file2 = argv[1];
160 	if (hflag && opt) {
161 		fprintf(stderr,
162 		    "diff: -h doesn't support -e, -f, -n, -c, or -I\n");
163 		done();
164 	}
165 	if (!strcmp(file1, "-"))
166 		stb1.st_mode = S_IFREG;
167 	else if (stat(file1, &stb1) < 0) {
168 		fprintf(stderr, "diff: ");
169 		perror(file1);
170 		done();
171 	}
172 	if (!strcmp(file2, "-"))
173 		stb2.st_mode = S_IFREG;
174 	else if (stat(file2, &stb2) < 0) {
175 		fprintf(stderr, "diff: ");
176 		perror(file2);
177 		done();
178 	}
179 	if ((stb1.st_mode & S_IFMT) == S_IFDIR &&
180 	    (stb2.st_mode & S_IFMT) == S_IFDIR) {
181 		diffdir(argv);
182 	} else
183 		diffreg();
184 	done();
185 }
186 
187 char *
188 savestr(cp)
189 	register char *cp;
190 {
191 	register char *dp = malloc(strlen(cp)+1);
192 
193 	if (dp == 0) {
194 		fprintf(stderr, "diff: ran out of memory\n");
195 		done();
196 	}
197 	strcpy(dp, cp);
198 	return (dp);
199 }
200 
201 min(a,b)
202 	int a,b;
203 {
204 
205 	return (a < b ? a : b);
206 }
207 
208 max(a,b)
209 	int a,b;
210 {
211 
212 	return (a > b ? a : b);
213 }
214 
215 done()
216 {
217 	if (tempfile)
218 		unlink(tempfile);
219 	exit(status);
220 }
221 
222 char *
223 talloc(n)
224 {
225 	register char *p;
226 
227 	if ((p = malloc((unsigned)n)) != NULL)
228 		return(p);
229 	noroom();
230 }
231 
232 char *
233 ralloc(p,n)
234 char *p;
235 {
236 	register char *q;
237 	char *realloc();
238 
239 	if ((q = realloc(p, (unsigned)n)) == NULL)
240 		noroom();
241 	return(q);
242 }
243 
244 noroom()
245 {
246 	fprintf(stderr, "diff: files too big, try -h\n");
247 	done();
248 }
249