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