11590Srgrimes/* 21590Srgrimes * Copyright (c) 1987, 1990, 1993, 1994 31590Srgrimes * The Regents of the University of California. All rights reserved. 41590Srgrimes * 51590Srgrimes * Redistribution and use in source and binary forms, with or without 61590Srgrimes * modification, are permitted provided that the following conditions 71590Srgrimes * are met: 81590Srgrimes * 1. Redistributions of source code must retain the above copyright 91590Srgrimes * notice, this list of conditions and the following disclaimer. 101590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111590Srgrimes * notice, this list of conditions and the following disclaimer in the 121590Srgrimes * documentation and/or other materials provided with the distribution. 131590Srgrimes * 4. Neither the name of the University nor the names of its contributors 141590Srgrimes * may be used to endorse or promote products derived from this software 151590Srgrimes * without specific prior written permission. 161590Srgrimes * 171590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 181590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 191590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 201590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 211590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 221590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 231590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 241590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 251590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 261590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 271590Srgrimes * SUCH DAMAGE. 281590Srgrimes */ 291590Srgrimes 301590Srgrimes#ifndef lint 3141568Sarchiestatic const char copyright[] = 321590Srgrimes"@(#) Copyright (c) 1987, 1990, 1993, 1994\n\ 331590Srgrimes The Regents of the University of California. All rights reserved.\n"; 3487241Smarkm#endif 351590Srgrimes 3687628Sdwmalone#if 0 371590Srgrimes#ifndef lint 3887628Sdwmalonestatic char sccsid[] = "@(#)cmp.c 8.3 (Berkeley) 4/2/94"; 3987241Smarkm#endif 4087628Sdwmalone#endif 411590Srgrimes 4287628Sdwmalone#include <sys/cdefs.h> 4387628Sdwmalone__FBSDID("$FreeBSD$"); 4487628Sdwmalone 451590Srgrimes#include <sys/types.h> 461590Srgrimes#include <sys/stat.h> 471590Srgrimes 481590Srgrimes#include <err.h> 49149388Sbrian#include <errno.h> 501590Srgrimes#include <fcntl.h> 511590Srgrimes#include <stdio.h> 521590Srgrimes#include <stdlib.h> 531590Srgrimes#include <string.h> 541590Srgrimes#include <unistd.h> 551590Srgrimes 561590Srgrimes#include "extern.h" 571590Srgrimes 5863157Sbrianint lflag, sflag, xflag, zflag; 591590Srgrimes 6092920Simpstatic void usage(void); 611590Srgrimes 621590Srgrimesint 63100815Sdwmalonemain(int argc, char *argv[]) 641590Srgrimes{ 651590Srgrimes struct stat sb1, sb2; 661590Srgrimes off_t skip1, skip2; 67149388Sbrian int ch, fd1, fd2, oflag, special; 6886099Sdwmalone const char *file1, *file2; 691590Srgrimes 70149388Sbrian oflag = O_RDONLY; 71149388Sbrian while ((ch = getopt(argc, argv, "hlsxz")) != -1) 721590Srgrimes switch (ch) { 73149388Sbrian case 'h': /* Don't follow symlinks */ 74149388Sbrian oflag |= O_NOFOLLOW; 75149388Sbrian break; 761590Srgrimes case 'l': /* print all differences */ 771590Srgrimes lflag = 1; 781590Srgrimes break; 791590Srgrimes case 's': /* silent run */ 801590Srgrimes sflag = 1; 8163157Sbrian zflag = 1; 821590Srgrimes break; 8360583Sphk case 'x': /* hex output */ 8460583Sphk lflag = 1; 8560583Sphk xflag = 1; 8660583Sphk break; 8763157Sbrian case 'z': /* compare size first */ 8863157Sbrian zflag = 1; 8963157Sbrian break; 901590Srgrimes case '?': 911590Srgrimes default: 921590Srgrimes usage(); 931590Srgrimes } 941590Srgrimes argv += optind; 951590Srgrimes argc -= optind; 961590Srgrimes 971590Srgrimes if (lflag && sflag) 9863157Sbrian errx(ERR_EXIT, "specifying -s with -l or -x is not permitted"); 991590Srgrimes 1001590Srgrimes if (argc < 2 || argc > 4) 1011590Srgrimes usage(); 1021590Srgrimes 1031590Srgrimes /* Backward compatibility -- handle "-" meaning stdin. */ 1041590Srgrimes special = 0; 1051590Srgrimes if (strcmp(file1 = argv[0], "-") == 0) { 1061590Srgrimes special = 1; 1071590Srgrimes fd1 = 0; 1081590Srgrimes file1 = "stdin"; 1091590Srgrimes } 110149388Sbrian else if ((fd1 = open(file1, oflag, 0)) < 0 && errno != EMLINK) { 1112149Sjkh if (!sflag) 1122149Sjkh err(ERR_EXIT, "%s", file1); 1132149Sjkh else 11497984Stjr exit(ERR_EXIT); 1152149Sjkh } 1161590Srgrimes if (strcmp(file2 = argv[1], "-") == 0) { 1171590Srgrimes if (special) 1181590Srgrimes errx(ERR_EXIT, 1191590Srgrimes "standard input may only be specified once"); 1201590Srgrimes special = 1; 1211590Srgrimes fd2 = 0; 1221590Srgrimes file2 = "stdin"; 1231590Srgrimes } 124149388Sbrian else if ((fd2 = open(file2, oflag, 0)) < 0 && errno != EMLINK) { 1252149Sjkh if (!sflag) 1262149Sjkh err(ERR_EXIT, "%s", file2); 1272149Sjkh else 12897984Stjr exit(ERR_EXIT); 1292149Sjkh } 1301590Srgrimes 13128421Sjlemon skip1 = argc > 2 ? strtol(argv[2], NULL, 0) : 0; 13228421Sjlemon skip2 = argc == 4 ? strtol(argv[3], NULL, 0) : 0; 1331590Srgrimes 134149388Sbrian if (fd1 == -1) { 135149388Sbrian if (fd2 == -1) { 136149388Sbrian c_link(file1, skip1, file2, skip2); 137149388Sbrian exit(0); 138149388Sbrian } else if (!sflag) 139149388Sbrian errx(ERR_EXIT, "%s: Not a symbolic link", file2); 140149388Sbrian else 141149388Sbrian exit(ERR_EXIT); 142149388Sbrian } else if (fd2 == -1) { 143149388Sbrian if (!sflag) 144149388Sbrian errx(ERR_EXIT, "%s: Not a symbolic link", file1); 145149388Sbrian else 146149388Sbrian exit(ERR_EXIT); 147149388Sbrian } 148149388Sbrian 1491590Srgrimes if (!special) { 1502149Sjkh if (fstat(fd1, &sb1)) { 1512149Sjkh if (!sflag) 1522149Sjkh err(ERR_EXIT, "%s", file1); 1532149Sjkh else 15497984Stjr exit(ERR_EXIT); 1552149Sjkh } 1561590Srgrimes if (!S_ISREG(sb1.st_mode)) 1571590Srgrimes special = 1; 1581590Srgrimes else { 1592149Sjkh if (fstat(fd2, &sb2)) { 1602149Sjkh if (!sflag) 1612149Sjkh err(ERR_EXIT, "%s", file2); 1622149Sjkh else 16397984Stjr exit(ERR_EXIT); 1642149Sjkh } 1651590Srgrimes if (!S_ISREG(sb2.st_mode)) 1661590Srgrimes special = 1; 1671590Srgrimes } 1681590Srgrimes } 1691590Srgrimes 1701590Srgrimes if (special) 1711590Srgrimes c_special(fd1, file1, skip1, fd2, file2, skip2); 17263843Ssheldonh else { 17363157Sbrian if (zflag && sb1.st_size != sb2.st_size) { 17463157Sbrian if (!sflag) 17563157Sbrian (void) printf("%s %s differ: size\n", 17663157Sbrian file1, file2); 17763157Sbrian exit(DIFF_EXIT); 17863157Sbrian } 1791590Srgrimes c_regular(fd1, file1, skip1, sb1.st_size, 1801590Srgrimes fd2, file2, skip2, sb2.st_size); 18163843Ssheldonh } 1821590Srgrimes exit(0); 1831590Srgrimes} 1841590Srgrimes 1851590Srgrimesstatic void 186100815Sdwmaloneusage(void) 1871590Srgrimes{ 1881590Srgrimes 1891590Srgrimes (void)fprintf(stderr, 190149388Sbrian "usage: cmp [-l | -s | -x] [-hz] file1 file2 [skip1 [skip2]]\n"); 1911590Srgrimes exit(ERR_EXIT); 1921590Srgrimes} 193