xref: /openbsd-src/usr.bin/diff/diff.c (revision f622a0cbe2a96c1f289b866f512bef8aad1ac517)
1 /*	$OpenBSD: diff.c,v 1.7 2003/06/25 19:56:57 millert 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 __dead void usage(void);
57 
58 int
59 main(int argc, char **argv)
60 {
61 	int ch;
62 
63 	ifdef1 = "FILE1";
64 	ifdef2 = "FILE2";
65 	status = 2;
66 	diffargv = argv;
67 
68 	while ((ch = getopt(argc, argv, "bC:cD:efhilnrS:stw")) != -1) {
69 		switch (ch) {
70 		case 'b':
71 			bflag++;
72 			break;
73 		case 'C':
74 			opt = D_CONTEXT;
75 			if (!isdigit(*optarg))
76 				usage();
77 			context = atoi(optarg);	/* XXX - use strtol */
78 			break;
79 		case 'c':
80 			opt = D_CONTEXT;
81 			context = 3;
82 			break;
83 		case 'D':
84 			/* -Dfoo = -E -1 -2foo */
85 			opt = D_IFDEF;
86 			ifdef1 = "";
87 			ifdef2 = optarg;
88 			wantelses++;
89 			break;
90 		case 'e':
91 			opt = D_EDIT;
92 			break;
93 		case 'f':
94 			opt = D_REVERSE;
95 			break;
96 		case 'h':
97 			hflag++;
98 			break;
99 		case 'i':
100 			iflag++;
101 			break;
102 		case 'l':
103 			lflag++;
104 			break;
105 		case 'n':
106 			opt = D_NREVERSE;
107 			break;
108 		case 'r':
109 			opt = D_REVERSE;
110 			break;
111 		case 'S':
112 			start = optarg;
113 			break;
114 		case 's':
115 			sflag++;
116 			break;
117 		case 't':
118 			tflag++;
119 			break;
120 		case 'w':
121 			wflag++;
122 			break;
123 		default:
124 			usage();
125 			break;
126 		}
127 	}
128 	argc -= optind;
129 	argv += optind;
130 
131 	if (argc != 2)
132 		errx(1, "two filename arguments required");
133 	file1 = argv[0];
134 	file2 = argv[1];
135 	if (hflag && opt)
136 		errx(1, "-h doesn't support -D, -c, -C, -e, -f, -I or -n");
137 	if (!strcmp(file1, "-"))
138 		stb1.st_mode = S_IFREG;
139 	else if (stat(file1, &stb1) < 0)
140 		err(1, "%s", file1);
141 	if (!strcmp(file2, "-"))
142 		stb2.st_mode = S_IFREG;
143 	else if (stat(file2, &stb2) < 0)
144 		err(1, "%s", file2);
145 	if ((stb1.st_mode & S_IFMT) == S_IFDIR &&
146 	    (stb2.st_mode & S_IFMT) == S_IFDIR) {
147 		diffdir(argv);
148 	} else
149 		diffreg();
150 	done(0);
151 }
152 
153 int
154 min(int a, int b)
155 {
156 
157 	return (a < b ? a : b);
158 }
159 
160 int
161 max(int a, int b)
162 {
163 
164 	return (a > b ? a : b);
165 }
166 
167 __dead void
168 done(int sig)
169 {
170 	if (tempfile)
171 		unlink(tempfile);
172 	if (sig)
173 		_exit(status);
174 	exit(status);
175 }
176 
177 void *
178 talloc(size_t n)
179 {
180 	void *p;
181 
182 	if ((p = malloc(n)) == NULL)
183 		noroom();
184 	return (p);
185 }
186 
187 void *
188 ralloc(void *p, size_t n)
189 {
190 	void *q;
191 
192 	if ((q = realloc(p, n)) == NULL)
193 		noroom();
194 	return (q);
195 }
196 
197 static void
198 noroom(void)
199 {
200 	warn("files too big, try -h");
201 	done(0);
202 }
203 
204 __dead void
205 usage(void)
206 {
207 	(void)fprintf(stderr, "usage: diff [-c | -C lines | -e | -f | -h | -n ] [-biwt] file1 file2\n"
208 	    "usage: diff [-Dstring] [-biw] file1 file2\n"
209 	    "usage: diff [-l] [-r] [-s] [-c | -C lines | -e | -f | -h | -n ] [-biwt]\n            [-Sname] dir1 dir2\n");
210 
211 	exit(1);
212 }
213