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