compare.c revision 44303
119304Speter/*- 219304Speter * Copyright (c) 1989, 1993 319304Speter * The Regents of the University of California. All rights reserved. 419304Speter * 519304Speter * Redistribution and use in source and binary forms, with or without 619304Speter * modification, are permitted provided that the following conditions 719304Speter * are met: 819304Speter * 1. Redistributions of source code must retain the above copyright 919304Speter * notice, this list of conditions and the following disclaimer. 1019304Speter * 2. Redistributions in binary form must reproduce the above copyright 1119304Speter * notice, this list of conditions and the following disclaimer in the 1219304Speter * documentation and/or other materials provided with the distribution. 13254225Speter * 3. All advertising materials mentioning features or use of this software 1419304Speter * must display the following acknowledgement: 1519304Speter * This product includes software developed by the University of 1619304Speter * California, Berkeley and its contributors. 1719304Speter * 4. Neither the name of the University nor the names of its contributors 1819304Speter * may be used to endorse or promote products derived from this software 1919304Speter * without specific prior written permission. 2019304Speter * 2119304Speter * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2219304Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2319304Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2419304Speter * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2519304Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2619304Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2719304Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2819304Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2919304Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3019304Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3119304Speter * SUCH DAMAGE. 3219304Speter */ 3319304Speter 34254225Speter#ifndef lint 3519304Speter#if 0 3619304Speterstatic char sccsid[] = "@(#)compare.c 8.1 (Berkeley) 6/6/93"; 3719304Speter#endif 3819304Speterstatic const char rcsid[] = 3919304Speter "$Id: compare.c,v 1.10 1998/08/02 14:41:34 bde Exp $"; 4019304Speter#endif /* not lint */ 4119304Speter 4219304Speter#include <sys/param.h> 4319304Speter#include <sys/stat.h> 4419304Speter#include <err.h> 4519304Speter#include <errno.h> 4619304Speter#include <fcntl.h> 4719304Speter#include <fts.h> 4819304Speter#ifdef MD5 4919304Speter#include <md5.h> 5019304Speter#endif 5119304Speter#ifdef SHA1 5219304Speter#include <sha.h> 5319304Speter#endif 5419304Speter#ifdef RMD160 5519304Speter#include <ripemd.h> 5619304Speter#endif 5719304Speter#include <stdio.h> 5819304Speter#include <time.h> 5919304Speter#include <unistd.h> 6019304Speter#include "mtree.h" 6119304Speter#include "extern.h" 6219304Speter 6319304Speterextern int uflag; 6419304Speterextern int lineno; 6519304Speter 6619304Speterstatic char *ftype __P((u_int)); 6719304Speter 6819304Speter#define INDENTNAMELEN 8 6919304Speter#define LABEL \ 7019304Speter if (!label++) { \ 7119304Speter len = printf("%s: ", RP(p)); \ 72254225Speter if (len > INDENTNAMELEN) { \ 7319304Speter tab = "\t"; \ 7419304Speter (void)printf("\n"); \ 7519304Speter } else { \ 7619304Speter tab = ""; \ 7719304Speter (void)printf("%*s", INDENTNAMELEN - (int)len, ""); \ 7819304Speter } \ 7919304Speter } 8019304Speter 8119304Speterint 8219304Spetercompare(name, s, p) 8319304Speter char *name; 8419304Speter register NODE *s; 8519304Speter register FTSENT *p; 8619304Speter{ 8719304Speter extern int uflag; 8819304Speter u_long len, val; 8919304Speter int fd, label; 9019304Speter char *cp, *tab = ""; 9119304Speter 9219304Speter label = 0; 9319304Speter switch(s->type) { 9419304Speter case F_BLOCK: 9519304Speter if (!S_ISBLK(p->fts_statp->st_mode)) 9619304Speter goto typeerr; 9719304Speter break; 9819304Speter case F_CHAR: 9919304Speter if (!S_ISCHR(p->fts_statp->st_mode)) 10019304Speter goto typeerr; 10119304Speter break; 10219304Speter case F_DIR: 10319304Speter if (!S_ISDIR(p->fts_statp->st_mode)) 10419304Speter goto typeerr; 10519304Speter break; 10619304Speter case F_FIFO: 10719304Speter if (!S_ISFIFO(p->fts_statp->st_mode)) 10819304Speter goto typeerr; 10919304Speter break; 11019304Speter case F_FILE: 11119304Speter if (!S_ISREG(p->fts_statp->st_mode)) 11219304Speter goto typeerr; 11319304Speter break; 11419304Speter case F_LINK: 11519304Speter if (!S_ISLNK(p->fts_statp->st_mode)) 11619304Speter goto typeerr; 11719304Speter break; 11819304Speter case F_SOCK: 11919304Speter if (!S_ISSOCK(p->fts_statp->st_mode)) { 12019304Spetertypeerr: LABEL; 12119304Speter (void)printf("\ttype (%s, %s)\n", 12219304Speter ftype(s->type), inotype(p->fts_statp->st_mode)); 12319304Speter } 12419304Speter break; 12519304Speter } 12619304Speter /* Set the uid/gid first, then set the mode. */ 12719304Speter if (s->flags & (F_UID | F_UNAME) && s->st_uid != p->fts_statp->st_uid) { 12819304Speter LABEL; 12919304Speter (void)printf("%suser (%lu, %lu", 13019304Speter tab, (u_long)s->st_uid, (u_long)p->fts_statp->st_uid); 13119304Speter if (uflag) 13219304Speter if (chown(p->fts_accpath, s->st_uid, -1)) 13319304Speter (void)printf(", not modified: %s)\n", 13419304Speter strerror(errno)); 13519304Speter else 13619304Speter (void)printf(", modified)\n"); 13719304Speter else 13819304Speter (void)printf(")\n"); 139254225Speter tab = "\t"; 14019304Speter } 14119304Speter if (s->flags & (F_GID | F_GNAME) && s->st_gid != p->fts_statp->st_gid) { 14219304Speter LABEL; 14319304Speter (void)printf("%sgid (%lu, %lu", 14419304Speter tab, (u_long)s->st_gid, (u_long)p->fts_statp->st_gid); 14519304Speter if (uflag) 14619304Speter if (chown(p->fts_accpath, -1, s->st_gid)) 14719304Speter (void)printf(", not modified: %s)\n", 14819304Speter strerror(errno)); 14919304Speter else 15019304Speter (void)printf(", modified)\n"); 15119304Speter else 15219304Speter (void)printf(")\n"); 15319304Speter tab = "\t"; 15419304Speter } 15519304Speter if (s->flags & F_MODE && 15619304Speter s->st_mode != (p->fts_statp->st_mode & MBITS)) { 15719304Speter LABEL; 15819304Speter (void)printf("%spermissions (%#o, %#o", 15919304Speter tab, s->st_mode, p->fts_statp->st_mode & MBITS); 16019304Speter if (uflag) 16119304Speter if (chmod(p->fts_accpath, s->st_mode)) 16219304Speter (void)printf(", not modified: %s)\n", 16319304Speter strerror(errno)); 16419304Speter else 16519304Speter (void)printf(", modified)\n"); 16619304Speter else 16719304Speter (void)printf(")\n"); 16819304Speter tab = "\t"; 16919304Speter } 17019304Speter if (s->flags & F_NLINK && s->type != F_DIR && 17119304Speter s->st_nlink != p->fts_statp->st_nlink) { 17219304Speter LABEL; 17319304Speter (void)printf("%slink count (%u, %u)\n", 17419304Speter tab, s->st_nlink, p->fts_statp->st_nlink); 17519304Speter tab = "\t"; 17619304Speter } 17719304Speter if (s->flags & F_SIZE && s->st_size != p->fts_statp->st_size) { 17819304Speter LABEL; 17919304Speter (void)printf("%ssize (%qd, %qd)\n", 18019304Speter tab, s->st_size, p->fts_statp->st_size); 18119304Speter tab = "\t"; 18219304Speter } 18319304Speter /* 18419304Speter * XXX 18519304Speter * Catches nano-second differences, but doesn't display them. 18619304Speter */ 18719304Speter if ((s->flags & F_TIME) && 18819304Speter ((s->st_mtimespec.tv_sec != p->fts_statp->st_mtimespec.tv_sec) || 18919304Speter (s->st_mtimespec.tv_nsec != p->fts_statp->st_mtimespec.tv_nsec))) { 19019304Speter LABEL; 19119304Speter (void)printf("%smodification time (%.24s, ", 19219304Speter tab, ctime(&s->st_mtimespec.tv_sec)); 19319304Speter (void)printf("%.24s)\n", 19419304Speter ctime(&p->fts_statp->st_mtimespec.tv_sec)); 19519304Speter tab = "\t"; 19619304Speter } 19719304Speter if (s->flags & F_CKSUM) 19819304Speter if ((fd = open(p->fts_accpath, O_RDONLY, 0)) < 0) { 19919304Speter LABEL; 20019304Speter (void)printf("%scksum: %s: %s\n", 201254225Speter tab, p->fts_accpath, strerror(errno)); 20219304Speter tab = "\t"; 20319304Speter } else if (crc(fd, &val, &len)) { 20419304Speter (void)close(fd); 20519304Speter LABEL; 20619304Speter (void)printf("%scksum: %s: %s\n", 20719304Speter tab, p->fts_accpath, strerror(errno)); 20819304Speter tab = "\t"; 20919304Speter } else { 21019304Speter (void)close(fd); 21119304Speter if (s->cksum != val) { 21219304Speter LABEL; 21319304Speter (void)printf("%scksum (%lu, %lu)\n", 21419304Speter tab, s->cksum, val); 21519304Speter } 21619304Speter tab = "\t"; 21719304Speter } 21819304Speter#ifdef MD5 21919304Speter if (s->flags & F_MD5) { 22019304Speter char *new_digest, buf[33]; 22119304Speter 22219304Speter new_digest = MD5File(p->fts_accpath, buf); 22319304Speter if (!new_digest) { 22419304Speter LABEL; 22519304Speter printf("%sMD5File: %s: %s\n", tab, p->fts_accpath, 22619304Speter strerror(errno)); 22719304Speter tab = "\t"; 22819304Speter } else if (strcmp(new_digest, s->md5digest)) { 22919304Speter LABEL; 23019304Speter printf("%sMD5 (%s, %s)\n", tab, s->md5digest, 23119304Speter new_digest); 23219304Speter tab = "\t"; 23319304Speter } 23419304Speter } 23519304Speter#endif /* MD5 */ 23619304Speter#ifdef SHA1 23719304Speter if (s->flags & F_SHA1) { 23819304Speter char *new_digest, buf[41]; 23919304Speter 24019304Speter new_digest = SHA1_File(p->fts_accpath, buf); 24119304Speter if (!new_digest) { 24219304Speter LABEL; 24319304Speter printf("%sSHA1_File: %s: %s\n", tab, p->fts_accpath, 24419304Speter strerror(errno)); 24519304Speter tab = "\t"; 24619304Speter } else if (strcmp(new_digest, s->sha1digest)) { 24719304Speter LABEL; 24819304Speter printf("%sSHA-1 (%s, %s)\n", tab, s->sha1digest, 24919304Speter new_digest); 25019304Speter tab = "\t"; 25119304Speter } 25219304Speter } 25319304Speter#endif /* SHA1 */ 25419304Speter#ifdef RMD160 25519304Speter if (s->flags & F_RMD160) { 25619304Speter char *new_digest, buf[41]; 25719304Speter 25819304Speter new_digest = RIPEMD160_File(p->fts_accpath, buf); 25919304Speter if (!new_digest) { 26019304Speter LABEL; 261254225Speter printf("%sRIPEMD160_File: %s: %s\n", tab, 26219304Speter p->fts_accpath, strerror(errno)); 26319304Speter tab = "\t"; 26419304Speter } else if (strcmp(new_digest, s->rmd160digest)) { 26519304Speter LABEL; 26619304Speter printf("%sRIPEMD160 (%s, %s)\n", tab, s->rmd160digest, 26719304Speter new_digest); 26819304Speter tab = "\t"; 26919304Speter } 27019304Speter } 27119304Speter#endif /* RMD160 */ 27219304Speter 27319304Speter if (s->flags & F_SLINK && strcmp(cp = rlink(name), s->slink)) { 27419304Speter LABEL; 27519304Speter (void)printf("%slink ref (%s, %s)\n", tab, cp, s->slink); 27619304Speter } 27719304Speter return (label); 27819304Speter} 27919304Speter 28019304Speterchar * 28119304Speterinotype(type) 28219304Speter u_int type; 28319304Speter{ 284 switch(type & S_IFMT) { 285 case S_IFBLK: 286 return ("block"); 287 case S_IFCHR: 288 return ("char"); 289 case S_IFDIR: 290 return ("dir"); 291 case S_IFIFO: 292 return ("fifo"); 293 case S_IFREG: 294 return ("file"); 295 case S_IFLNK: 296 return ("link"); 297 case S_IFSOCK: 298 return ("socket"); 299 default: 300 return ("unknown"); 301 } 302 /* NOTREACHED */ 303} 304 305static char * 306ftype(type) 307 u_int type; 308{ 309 switch(type) { 310 case F_BLOCK: 311 return ("block"); 312 case F_CHAR: 313 return ("char"); 314 case F_DIR: 315 return ("dir"); 316 case F_FIFO: 317 return ("fifo"); 318 case F_FILE: 319 return ("file"); 320 case F_LINK: 321 return ("link"); 322 case F_SOCK: 323 return ("socket"); 324 default: 325 return ("unknown"); 326 } 327 /* NOTREACHED */ 328} 329 330char * 331rlink(name) 332 char *name; 333{ 334 static char lbuf[MAXPATHLEN]; 335 register int len; 336 337 if ((len = readlink(name, lbuf, sizeof(lbuf) - 1)) == -1) 338 err(1, "line %d: %s", lineno, name); 339 lbuf[len] = '\0'; 340 return (lbuf); 341} 342