1*9de32c1bSmillert /* $OpenBSD: diff.c,v 1.9 2003/06/25 22:14:43 millert Exp $ */ 2d0c3f575Sderaadt 3d0c3f575Sderaadt /* 4d0c3f575Sderaadt * Copyright (C) Caldera International Inc. 2001-2002. 5d0c3f575Sderaadt * All rights reserved. 6d0c3f575Sderaadt * 7d0c3f575Sderaadt * Redistribution and use in source and binary forms, with or without 8d0c3f575Sderaadt * modification, are permitted provided that the following conditions 9d0c3f575Sderaadt * are met: 10d0c3f575Sderaadt * 1. Redistributions of source code and documentation must retain the above 11d0c3f575Sderaadt * copyright notice, this list of conditions and the following disclaimer. 12d0c3f575Sderaadt * 2. Redistributions in binary form must reproduce the above copyright 13d0c3f575Sderaadt * notice, this list of conditions and the following disclaimer in the 14d0c3f575Sderaadt * documentation and/or other materials provided with the distribution. 15d0c3f575Sderaadt * 3. All advertising materials mentioning features or use of this software 16d0c3f575Sderaadt * must display the following acknowledgement: 17d0c3f575Sderaadt * This product includes software developed or owned by Caldera 18d0c3f575Sderaadt * International, Inc. 19d0c3f575Sderaadt * 4. Neither the name of Caldera International, Inc. nor the names of other 20d0c3f575Sderaadt * contributors may be used to endorse or promote products derived from 21d0c3f575Sderaadt * this software without specific prior written permission. 22d0c3f575Sderaadt * 23d0c3f575Sderaadt * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA 24d0c3f575Sderaadt * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR 25d0c3f575Sderaadt * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 26d0c3f575Sderaadt * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 27d0c3f575Sderaadt * IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE FOR ANY DIRECT, 28d0c3f575Sderaadt * INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 29d0c3f575Sderaadt * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 30d0c3f575Sderaadt * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31d0c3f575Sderaadt * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 32d0c3f575Sderaadt * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 33d0c3f575Sderaadt * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34d0c3f575Sderaadt * POSSIBILITY OF SUCH DAMAGE. 35d0c3f575Sderaadt */ 36d0c3f575Sderaadt 3726da422aStedu #include <stdlib.h> 3826da422aStedu #include <unistd.h> 39ae8d569bSderaadt 40ae8d569bSderaadt #include "diff.h" 41ae8d569bSderaadt #include "pathnames.h" 42ae8d569bSderaadt 4326da422aStedu #if 0 4426da422aStedu static char const sccsid[] = "@(#)diff.c 4.7 5/11/89"; 4526da422aStedu #endif 4626da422aStedu 47ae8d569bSderaadt /* 48ae8d569bSderaadt * diff - driver and subroutines 49ae8d569bSderaadt */ 50ae8d569bSderaadt 51ae8d569bSderaadt char diff[] = _PATH_DIFF; 52ae8d569bSderaadt char diffh[] = _PATH_DIFFH; 53ae8d569bSderaadt char pr[] = _PATH_PR; 54ae8d569bSderaadt 5526da422aStedu static void noroom(void); 56c42aed39Smillert __dead void usage(void); 57ae8d569bSderaadt 5826da422aStedu int 5926da422aStedu main(int argc, char **argv) 6026da422aStedu { 61c42aed39Smillert int ch; 6226da422aStedu 6326da422aStedu ifdef1 = "FILE1"; 6426da422aStedu ifdef2 = "FILE2"; 65ae8d569bSderaadt status = 2; 66ae8d569bSderaadt diffargv = argv; 67c42aed39Smillert 68*9de32c1bSmillert while ((ch = getopt(argc, argv, "bC:cD:efhilnrS:stU:uw")) != -1) { 69c42aed39Smillert switch (ch) { 70ae8d569bSderaadt case 'b': 71c42aed39Smillert bflag++; 72c42aed39Smillert break; 73c42aed39Smillert case 'C': 74c42aed39Smillert opt = D_CONTEXT; 75c42aed39Smillert if (!isdigit(*optarg)) 76c42aed39Smillert usage(); 77c42aed39Smillert context = atoi(optarg); /* XXX - use strtol */ 78c42aed39Smillert break; 79ae8d569bSderaadt case 'c': 80ae8d569bSderaadt opt = D_CONTEXT; 81ae8d569bSderaadt context = 3; 82c42aed39Smillert break; 83c42aed39Smillert case 'D': 84c42aed39Smillert /* -Dfoo = -E -1 -2foo */ 85c42aed39Smillert opt = D_IFDEF; 86c42aed39Smillert ifdef1 = ""; 87c42aed39Smillert ifdef2 = optarg; 88c42aed39Smillert wantelses++; 89c42aed39Smillert break; 90c42aed39Smillert case 'e': 91c42aed39Smillert opt = D_EDIT; 92c42aed39Smillert break; 93c42aed39Smillert case 'f': 94c42aed39Smillert opt = D_REVERSE; 95c42aed39Smillert break; 96ae8d569bSderaadt case 'h': 97ae8d569bSderaadt hflag++; 98c42aed39Smillert break; 99c42aed39Smillert case 'i': 100c42aed39Smillert iflag++; 101c42aed39Smillert break; 102ae8d569bSderaadt case 'l': 103ae8d569bSderaadt lflag++; 104c42aed39Smillert break; 105c42aed39Smillert case 'n': 106c42aed39Smillert opt = D_NREVERSE; 107c42aed39Smillert break; 108c42aed39Smillert case 'r': 109c42aed39Smillert opt = D_REVERSE; 110c42aed39Smillert break; 111c42aed39Smillert case 'S': 112c42aed39Smillert start = optarg; 113c42aed39Smillert break; 114c42aed39Smillert case 's': 115c42aed39Smillert sflag++; 116c42aed39Smillert break; 117c42aed39Smillert case 't': 118c42aed39Smillert tflag++; 119c42aed39Smillert break; 120*9de32c1bSmillert case 'U': 121*9de32c1bSmillert opt = D_UNIFIED; 122*9de32c1bSmillert if (!isdigit(*optarg)) 123*9de32c1bSmillert usage(); 124*9de32c1bSmillert context = atoi(optarg); /* XXX - use strtol */ 125*9de32c1bSmillert break; 126*9de32c1bSmillert case 'u': 127*9de32c1bSmillert opt = D_UNIFIED; 128*9de32c1bSmillert context = 3; 129*9de32c1bSmillert break; 130c42aed39Smillert case 'w': 131c42aed39Smillert wflag++; 132c42aed39Smillert break; 133ae8d569bSderaadt default: 134c42aed39Smillert usage(); 135c42aed39Smillert break; 136ae8d569bSderaadt } 137ae8d569bSderaadt } 138c42aed39Smillert argc -= optind; 139c42aed39Smillert argv += optind; 140c42aed39Smillert 141c42aed39Smillert if (argc != 2) 142c42aed39Smillert errx(1, "two filename arguments required"); 143ae8d569bSderaadt file1 = argv[0]; 144ae8d569bSderaadt file2 = argv[1]; 145c42aed39Smillert if (hflag && opt) 146*9de32c1bSmillert errx(1, "-h doesn't support -D, -c, -C, -e, -f, -I, -n, -u or -U"); 147ae8d569bSderaadt if (!strcmp(file1, "-")) 148ae8d569bSderaadt stb1.st_mode = S_IFREG; 149c42aed39Smillert else if (stat(file1, &stb1) < 0) 150c42aed39Smillert err(1, "%s", file1); 151ae8d569bSderaadt if (!strcmp(file2, "-")) 152ae8d569bSderaadt stb2.st_mode = S_IFREG; 153c42aed39Smillert else if (stat(file2, &stb2) < 0) 154c42aed39Smillert err(1, "%s", file2); 15549dffe13Smillert if (S_ISDIR(stb1.st_mode) && S_ISDIR(stb2.st_mode)) 156ae8d569bSderaadt diffdir(argv); 15749dffe13Smillert else 158ae8d569bSderaadt diffreg(); 159a6a14831Sderaadt done(0); 160ae8d569bSderaadt } 161ae8d569bSderaadt 16226da422aStedu int 16326da422aStedu min(int a, int b) 164ae8d569bSderaadt { 165ae8d569bSderaadt 166ae8d569bSderaadt return (a < b ? a : b); 167ae8d569bSderaadt } 168ae8d569bSderaadt 16926da422aStedu int 17026da422aStedu max(int a, int b) 171ae8d569bSderaadt { 172ae8d569bSderaadt 173ae8d569bSderaadt return (a > b ? a : b); 174ae8d569bSderaadt } 175ae8d569bSderaadt 176c42aed39Smillert __dead void 177a6a14831Sderaadt done(int sig) 178ae8d569bSderaadt { 179ae8d569bSderaadt if (tempfile) 180ae8d569bSderaadt unlink(tempfile); 181a6a14831Sderaadt if (sig) 182a6a14831Sderaadt _exit(status); 183ae8d569bSderaadt exit(status); 184ae8d569bSderaadt } 185ae8d569bSderaadt 18626da422aStedu void * 18749dffe13Smillert emalloc(size_t n) 188ae8d569bSderaadt { 18926da422aStedu void *p; 190ae8d569bSderaadt 19126da422aStedu if ((p = malloc(n)) == NULL) 19226da422aStedu noroom(); 19326da422aStedu return (p); 19426da422aStedu } 19526da422aStedu 19626da422aStedu void * 19749dffe13Smillert erealloc(void *p, size_t n) 19826da422aStedu { 19926da422aStedu void *q; 20026da422aStedu 20126da422aStedu if ((q = realloc(p, n)) == NULL) 202ae8d569bSderaadt noroom(); 203ae8d569bSderaadt return (q); 204ae8d569bSderaadt } 205ae8d569bSderaadt 20626da422aStedu static void 20726da422aStedu noroom(void) 208ae8d569bSderaadt { 209c42aed39Smillert warn("files too big, try -h"); 210a6a14831Sderaadt done(0); 211ae8d569bSderaadt } 212c42aed39Smillert 213c42aed39Smillert __dead void 214c42aed39Smillert usage(void) 215c42aed39Smillert { 216*9de32c1bSmillert (void)fprintf(stderr, "usage: diff [-bitw] [-c | -e | -f | -h | -n | -u ] file1 file2\n" 217*9de32c1bSmillert " diff [-biw] -Dstring file1 file2\n" 218*9de32c1bSmillert " diff [-biwt] [-c | -e | -f | -h | -n | -u ] [-l] [-r] [-s] [-Sname]\n dir1 dir2\n" 219*9de32c1bSmillert " diff [-bitw] -Cnumber [file1 file2 | dir1 dir2]\n" 220*9de32c1bSmillert " diff [-bitw] -Unumber [file1 file2 | dir1 dir2]\n"); 221c42aed39Smillert 222c42aed39Smillert exit(1); 223c42aed39Smillert } 224