xref: /openbsd-src/usr.bin/diff/diff.c (revision a6a14831a52dc2f752e78bcf9046befbc1121990)
1 /*	$OpenBSD: diff.c,v 1.4 2003/06/25 03:37:32 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 #include <stdlib.h>
38 #include <unistd.h>
39 
40 #include "diff.h"
41 #include "pathnames.h"
42 
43 #if 0
44 static char const sccsid[] = "@(#)diff.c 4.7 5/11/89";
45 #endif
46 
47 /*
48  * diff - driver and subroutines
49  */
50 
51 char diff[] = _PATH_DIFF;
52 char diffh[] = _PATH_DIFFH;
53 char pr[] = _PATH_PR;
54 
55 static void noroom(void);
56 
57 int
58 main(int argc, char **argv)
59 {
60 	char *argp;
61 
62 	ifdef1 = "FILE1";
63 	ifdef2 = "FILE2";
64 	status = 2;
65 	diffargv = argv;
66 	argc--, argv++;
67 	while (argc > 2 && argv[0][0] == '-') {
68 		argp = &argv[0][1];
69 		argv++, argc--;
70 		while (*argp)
71 			switch (*argp++) {
72 #ifdef notdef
73 			case 'I':
74 				opt = D_IFDEF;
75 				wantelses = 0;
76 				continue;
77 			case 'E':
78 				opt = D_IFDEF;
79 				wantelses = 1;
80 				continue;
81 			case '1':
82 				opt = D_IFDEF;
83 				ifdef1 = argp;
84 				*--argp = 0;
85 				continue;
86 #endif
87 			case 'D':
88 				/* -Dfoo = -E -1 -2foo */
89 				wantelses = 1;
90 				ifdef1 = "";
91 				/* fall through */
92 #ifdef notdef
93 			case '2':
94 #endif
95 				opt = D_IFDEF;
96 				ifdef2 = argp;
97 				*--argp = 0;
98 				continue;
99 			case 'e':
100 				opt = D_EDIT;
101 				continue;
102 			case 'f':
103 				opt = D_REVERSE;
104 				continue;
105 			case 'n':
106 				opt = D_NREVERSE;
107 				continue;
108 			case 'b':
109 				bflag = 1;
110 				continue;
111 			case 'w':
112 				wflag = 1;
113 				continue;
114 			case 'i':
115 				iflag = 1;
116 				continue;
117 			case 't':
118 				tflag = 1;
119 				continue;
120 			case 'c':
121 				opt = D_CONTEXT;
122 				if (isdigit(*argp)) {
123 					context = atoi(argp);
124 					while (isdigit(*argp))
125 						argp++;
126 					if (*argp) {
127 						fprintf(stderr,
128 						    "diff: -c: bad count\n");
129 						done(0);
130 					}
131 					argp = "";
132 				} else
133 					context = 3;
134 				continue;
135 			case 'h':
136 				hflag++;
137 				continue;
138 			case 'S':
139 				if (*argp == 0) {
140 					fprintf(stderr, "diff: use -Sstart\n");
141 					done(0);
142 				}
143 				start = argp;
144 				*--argp = 0;	/* don't pass it on */
145 				continue;
146 			case 'r':
147 				rflag++;
148 				continue;
149 			case 's':
150 				sflag++;
151 				continue;
152 			case 'l':
153 				lflag++;
154 				continue;
155 			default:
156 				fprintf(stderr, "diff: -%s: unknown option\n",
157 				    --argp);
158 				done(0);
159 			}
160 	}
161 	if (argc != 2) {
162 		fprintf(stderr, "diff: two filename arguments required\n");
163 		done(0);
164 	}
165 	file1 = argv[0];
166 	file2 = argv[1];
167 	if (hflag && opt) {
168 		fprintf(stderr,
169 		    "diff: -h doesn't support -e, -f, -n, -c, or -I\n");
170 		done(0);
171 	}
172 	if (!strcmp(file1, "-"))
173 		stb1.st_mode = S_IFREG;
174 	else if (stat(file1, &stb1) < 0) {
175 		fprintf(stderr, "diff: ");
176 		perror(file1);
177 		done(0);
178 	}
179 	if (!strcmp(file2, "-"))
180 		stb2.st_mode = S_IFREG;
181 	else if (stat(file2, &stb2) < 0) {
182 		fprintf(stderr, "diff: ");
183 		perror(file2);
184 		done(0);
185 	}
186 	if ((stb1.st_mode & S_IFMT) == S_IFDIR &&
187 	    (stb2.st_mode & S_IFMT) == S_IFDIR) {
188 		diffdir(argv);
189 	} else
190 		diffreg();
191 	done(0);
192 	/* notreached */
193 	return (0);
194 }
195 
196 int
197 min(int a, int b)
198 {
199 
200 	return (a < b ? a : b);
201 }
202 
203 int
204 max(int a, int b)
205 {
206 
207 	return (a > b ? a : b);
208 }
209 
210 void
211 done(int sig)
212 {
213 	if (tempfile)
214 		unlink(tempfile);
215 	if (sig)
216 		_exit(status);
217 	exit(status);
218 }
219 
220 void
221 catchsig(int sigraised)
222 {
223 	/* print something? */
224 	done(0);
225 }
226 
227 void *
228 talloc(size_t n)
229 {
230 	void *p;
231 
232 	if ((p = malloc(n)) == NULL)
233 		noroom();
234 	return (p);
235 }
236 
237 void *
238 ralloc(void *p, size_t n)
239 {
240 	void *q;
241 
242 	if ((q = realloc(p, n)) == NULL)
243 		noroom();
244 	return (q);
245 }
246 
247 static void
248 noroom(void)
249 {
250 	fprintf(stderr, "diff: files too big, try -h\n");
251 	done(0);
252 }
253