cmp.c revision 100815
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 * 3. All advertising materials mentioning features or use of this software 141590Srgrimes * must display the following acknowledgement: 151590Srgrimes * This product includes software developed by the University of 161590Srgrimes * California, Berkeley and its contributors. 171590Srgrimes * 4. Neither the name of the University nor the names of its contributors 181590Srgrimes * may be used to endorse or promote products derived from this software 191590Srgrimes * without specific prior written permission. 201590Srgrimes * 211590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311590Srgrimes * SUCH DAMAGE. 321590Srgrimes */ 331590Srgrimes 341590Srgrimes#ifndef lint 3541568Sarchiestatic const char copyright[] = 361590Srgrimes"@(#) Copyright (c) 1987, 1990, 1993, 1994\n\ 371590Srgrimes The Regents of the University of California. All rights reserved.\n"; 3887241Smarkm#endif 391590Srgrimes 4087628Sdwmalone#if 0 411590Srgrimes#ifndef lint 4287628Sdwmalonestatic char sccsid[] = "@(#)cmp.c 8.3 (Berkeley) 4/2/94"; 4387241Smarkm#endif 4487628Sdwmalone#endif 451590Srgrimes 4687628Sdwmalone#include <sys/cdefs.h> 4787628Sdwmalone__FBSDID("$FreeBSD: head/usr.bin/cmp/cmp.c 100815 2002-07-28 15:13:17Z dwmalone $"); 4887628Sdwmalone 491590Srgrimes#include <sys/types.h> 501590Srgrimes#include <sys/stat.h> 511590Srgrimes 521590Srgrimes#include <err.h> 531590Srgrimes#include <fcntl.h> 541590Srgrimes#include <stdio.h> 551590Srgrimes#include <stdlib.h> 561590Srgrimes#include <string.h> 571590Srgrimes#include <unistd.h> 581590Srgrimes 591590Srgrimes#include "extern.h" 601590Srgrimes 6163157Sbrianint lflag, sflag, xflag, zflag; 621590Srgrimes 6392920Simpstatic void usage(void); 641590Srgrimes 651590Srgrimesint 66100815Sdwmalonemain(int argc, char *argv[]) 671590Srgrimes{ 681590Srgrimes struct stat sb1, sb2; 691590Srgrimes off_t skip1, skip2; 701590Srgrimes int ch, fd1, fd2, special; 7186099Sdwmalone const char *file1, *file2; 721590Srgrimes 7397985Stjr while ((ch = getopt(argc, argv, "lsxz")) != -1) 741590Srgrimes switch (ch) { 751590Srgrimes case 'l': /* print all differences */ 761590Srgrimes lflag = 1; 771590Srgrimes break; 781590Srgrimes case 's': /* silent run */ 791590Srgrimes sflag = 1; 8063157Sbrian zflag = 1; 811590Srgrimes break; 8260583Sphk case 'x': /* hex output */ 8360583Sphk lflag = 1; 8460583Sphk xflag = 1; 8560583Sphk break; 8663157Sbrian case 'z': /* compare size first */ 8763157Sbrian zflag = 1; 8863157Sbrian break; 891590Srgrimes case '?': 901590Srgrimes default: 911590Srgrimes usage(); 921590Srgrimes } 931590Srgrimes argv += optind; 941590Srgrimes argc -= optind; 951590Srgrimes 961590Srgrimes if (lflag && sflag) 9763157Sbrian errx(ERR_EXIT, "specifying -s with -l or -x is not permitted"); 981590Srgrimes 991590Srgrimes if (argc < 2 || argc > 4) 1001590Srgrimes usage(); 1011590Srgrimes 1021590Srgrimes /* Backward compatibility -- handle "-" meaning stdin. */ 1031590Srgrimes special = 0; 1041590Srgrimes if (strcmp(file1 = argv[0], "-") == 0) { 1051590Srgrimes special = 1; 1061590Srgrimes fd1 = 0; 1071590Srgrimes file1 = "stdin"; 1081590Srgrimes } 1092149Sjkh else if ((fd1 = open(file1, O_RDONLY, 0)) < 0) { 1102149Sjkh if (!sflag) 1112149Sjkh err(ERR_EXIT, "%s", file1); 1122149Sjkh else 11397984Stjr exit(ERR_EXIT); 1142149Sjkh } 1151590Srgrimes if (strcmp(file2 = argv[1], "-") == 0) { 1161590Srgrimes if (special) 1171590Srgrimes errx(ERR_EXIT, 1181590Srgrimes "standard input may only be specified once"); 1191590Srgrimes special = 1; 1201590Srgrimes fd2 = 0; 1211590Srgrimes file2 = "stdin"; 1221590Srgrimes } 1232149Sjkh else if ((fd2 = open(file2, O_RDONLY, 0)) < 0) { 1242149Sjkh if (!sflag) 1252149Sjkh err(ERR_EXIT, "%s", file2); 1262149Sjkh else 12797984Stjr exit(ERR_EXIT); 1282149Sjkh } 1291590Srgrimes 13028421Sjlemon skip1 = argc > 2 ? strtol(argv[2], NULL, 0) : 0; 13128421Sjlemon skip2 = argc == 4 ? strtol(argv[3], NULL, 0) : 0; 1321590Srgrimes 1331590Srgrimes if (!special) { 1342149Sjkh if (fstat(fd1, &sb1)) { 1352149Sjkh if (!sflag) 1362149Sjkh err(ERR_EXIT, "%s", file1); 1372149Sjkh else 13897984Stjr exit(ERR_EXIT); 1392149Sjkh } 1401590Srgrimes if (!S_ISREG(sb1.st_mode)) 1411590Srgrimes special = 1; 1421590Srgrimes else { 1432149Sjkh if (fstat(fd2, &sb2)) { 1442149Sjkh if (!sflag) 1452149Sjkh err(ERR_EXIT, "%s", file2); 1462149Sjkh else 14797984Stjr exit(ERR_EXIT); 1482149Sjkh } 1491590Srgrimes if (!S_ISREG(sb2.st_mode)) 1501590Srgrimes special = 1; 1511590Srgrimes } 1521590Srgrimes } 1531590Srgrimes 1541590Srgrimes if (special) 1551590Srgrimes c_special(fd1, file1, skip1, fd2, file2, skip2); 15663843Ssheldonh else { 15763157Sbrian if (zflag && sb1.st_size != sb2.st_size) { 15863157Sbrian if (!sflag) 15963157Sbrian (void) printf("%s %s differ: size\n", 16063157Sbrian file1, file2); 16163157Sbrian exit(DIFF_EXIT); 16263157Sbrian } 1631590Srgrimes c_regular(fd1, file1, skip1, sb1.st_size, 1641590Srgrimes fd2, file2, skip2, sb2.st_size); 16563843Ssheldonh } 1661590Srgrimes exit(0); 1671590Srgrimes} 1681590Srgrimes 1691590Srgrimesstatic void 170100815Sdwmaloneusage(void) 1711590Srgrimes{ 1721590Srgrimes 1731590Srgrimes (void)fprintf(stderr, 17463157Sbrian "usage: cmp [-l | -s | -x] [-z] file1 file2 [skip1 [skip2]]\n"); 1751590Srgrimes exit(ERR_EXIT); 1761590Srgrimes} 177