compare.c revision 259065
1253789Srpaulo/* $NetBSD: compare.c,v 1.58 2013/11/21 18:39:50 christos Exp $ */ 2253789Srpaulo 3253789Srpaulo/*- 4253789Srpaulo * Copyright (c) 1989, 1993 5253789Srpaulo * The Regents of the University of California. All rights reserved. 6253789Srpaulo * 7253789Srpaulo * Redistribution and use in source and binary forms, with or without 8253789Srpaulo * modification, are permitted provided that the following conditions 9253789Srpaulo * are met: 10253789Srpaulo * 1. Redistributions of source code must retain the above copyright 11253789Srpaulo * notice, this list of conditions and the following disclaimer. 12253789Srpaulo * 2. Redistributions in binary form must reproduce the above copyright 13253789Srpaulo * notice, this list of conditions and the following disclaimer in the 14253789Srpaulo * documentation and/or other materials provided with the distribution. 15253789Srpaulo * 3. Neither the name of the University nor the names of its contributors 16253789Srpaulo * may be used to endorse or promote products derived from this software 17253789Srpaulo * without specific prior written permission. 18253789Srpaulo * 19253789Srpaulo * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20253789Srpaulo * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21253789Srpaulo * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22253789Srpaulo * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23253789Srpaulo * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24253789Srpaulo * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25253789Srpaulo * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26253789Srpaulo * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27253789Srpaulo * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28253789Srpaulo * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29253789Srpaulo * SUCH DAMAGE. 30253789Srpaulo */ 31253789Srpaulo 32253789Srpaulo#if HAVE_NBTOOL_CONFIG_H 33253789Srpaulo#include "nbtool_config.h" 34253789Srpaulo#endif 35253789Srpaulo 36253789Srpaulo#include <sys/cdefs.h> 37253789Srpaulo#if defined(__RCSID) && !defined(lint) 38253789Srpaulo#if 0 39253789Srpaulostatic char sccsid[] = "@(#)compare.c 8.1 (Berkeley) 6/6/93"; 40253789Srpaulo#else 41253789Srpaulo__RCSID("$NetBSD: compare.c,v 1.58 2013/11/21 18:39:50 christos Exp $"); 42253789Srpaulo#endif 43253789Srpaulo#endif /* not lint */ 44253789Srpaulo 45253789Srpaulo#include <sys/param.h> 46253789Srpaulo#include <sys/stat.h> 47253789Srpaulo 48253789Srpaulo#include <errno.h> 49253789Srpaulo#include <fcntl.h> 50253789Srpaulo#include <stdio.h> 51253789Srpaulo#include <stdint.h> 52253789Srpaulo#include <stdlib.h> 53253789Srpaulo#include <string.h> 54253789Srpaulo#include <time.h> 55253789Srpaulo#include <unistd.h> 56253789Srpaulo 57253789Srpaulo#ifndef NO_MD5 58253789Srpaulo#include <md5.h> 59253789Srpaulo#endif 60253789Srpaulo#ifndef NO_RMD160 61253789Srpaulo#include <rmd160.h> 62253789Srpaulo#endif 63253789Srpaulo#ifndef NO_SHA1 64253789Srpaulo#include <sha1.h> 65253789Srpaulo#endif 66253789Srpaulo#ifndef NO_SHA2 67253789Srpaulo#include <sha2.h> 68253789Srpaulo#endif 69253789Srpaulo 70253789Srpaulo#include "extern.h" 71253789Srpaulo 72253789Srpaulo#define INDENTNAMELEN 8 73253789Srpaulo#define MARK \ 74253789Srpaulodo { \ 75253789Srpaulo if (flavor == F_FREEBSD9) { \ 76253789Srpaulo len = printf("%s changed\n", RP(p)); \ 77253789Srpaulo tab = "\t"; \ 78253789Srpaulo } else { \ 79253789Srpaulo len = printf("%s: ", RP(p)); \ 80253789Srpaulo if (len > INDENTNAMELEN) { \ 81253789Srpaulo tab = "\t"; \ 82253789Srpaulo printf("\n"); \ 83253789Srpaulo } else { \ 84253789Srpaulo tab = ""; \ 85253789Srpaulo printf("%*s", INDENTNAMELEN - (int)len, ""); \ 86253789Srpaulo } \ 87253789Srpaulo } \ 88253789Srpaulo} while (0) 89253789Srpaulo#define LABEL if (!label++) MARK 90253789Srpaulo 91253789Srpaulo#if HAVE_STRUCT_STAT_ST_FLAGS 92253789Srpaulo 93253789Srpaulo 94253789Srpaulo#define CHANGEFLAGS \ 95253789Srpaulo if (flags != p->fts_statp->st_flags) { \ 96253789Srpaulo char *sf; \ 97253789Srpaulo if (!label) { \ 98253789Srpaulo MARK; \ 99253789Srpaulo sf = flags_to_string(p->fts_statp->st_flags, "none"); \ 100253789Srpaulo printf("%sflags (\"%s\"", tab, sf); \ 101273898Shselasky free(sf); \ 102253789Srpaulo } \ 103253789Srpaulo if (lchflags(p->fts_accpath, flags)) { \ 104253789Srpaulo label++; \ 105253789Srpaulo printf(", not modified: %s)\n", \ 106253789Srpaulo strerror(errno)); \ 107253789Srpaulo } else { \ 108253789Srpaulo sf = flags_to_string(flags, "none"); \ 109253789Srpaulo printf(", modified to \"%s\")\n", sf); \ 110253789Srpaulo free(sf); \ 111253789Srpaulo } \ 112253789Srpaulo } 113253789Srpaulo 114253789Srpaulo/* SETFLAGS: 115253789Srpaulo * given pflags, additionally set those flags specified in s->st_flags and 116253789Srpaulo * selected by mask (the other flags are left unchanged). 117253789Srpaulo */ 118253789Srpaulo#define SETFLAGS(pflags, mask) \ 119253789Srpaulodo { \ 120253789Srpaulo flags = (s->st_flags & (mask)) | (pflags); \ 121253789Srpaulo CHANGEFLAGS; \ 122253789Srpaulo} while (0) 123253789Srpaulo 124253789Srpaulo/* CLEARFLAGS: 125253789Srpaulo * given pflags, reset the flags specified in s->st_flags and selected by mask 126267349Shselasky * (the other flags are left unchanged). 127267349Shselasky */ 128253789Srpaulo#define CLEARFLAGS(pflags, mask) \ 129253789Srpaulodo { \ 130253789Srpaulo flags = (~(s->st_flags & (mask)) & CH_MASK) & (pflags); \ 131253789Srpaulo CHANGEFLAGS; \ 132253789Srpaulo} while (0) 133253789Srpaulo#endif /* HAVE_STRUCT_STAT_ST_FLAGS */ 134253789Srpaulo 135253789Srpauloint 136253789Srpaulocompare(NODE *s, FTSENT *p) 137253789Srpaulo{ 138253789Srpaulo u_int32_t len, val, flags; 139253789Srpaulo int fd, label; 140253789Srpaulo const char *cp, *tab; 141253789Srpaulo#if !defined(NO_MD5) || !defined(NO_RMD160) || !defined(NO_SHA1) || !defined(NO_SHA2) 142253789Srpaulo char *digestbuf; 143253789Srpaulo#endif 144253789Srpaulo 145253789Srpaulo tab = NULL; 146253789Srpaulo label = 0; 147253789Srpaulo switch(s->type) { 148253789Srpaulo case F_BLOCK: 149253789Srpaulo if (!S_ISBLK(p->fts_statp->st_mode)) 150253789Srpaulo goto typeerr; 151253789Srpaulo break; 152253789Srpaulo case F_CHAR: 153253789Srpaulo if (!S_ISCHR(p->fts_statp->st_mode)) 154253789Srpaulo goto typeerr; 155253789Srpaulo break; 156253789Srpaulo case F_DIR: 157253789Srpaulo if (!S_ISDIR(p->fts_statp->st_mode)) 158253789Srpaulo goto typeerr; 159253789Srpaulo break; 160253789Srpaulo case F_FIFO: 161253789Srpaulo if (!S_ISFIFO(p->fts_statp->st_mode)) 162253789Srpaulo goto typeerr; 163253789Srpaulo break; 164253789Srpaulo case F_FILE: 165253789Srpaulo if (!S_ISREG(p->fts_statp->st_mode)) 166253789Srpaulo goto typeerr; 167253789Srpaulo break; 168253789Srpaulo case F_LINK: 169253789Srpaulo if (!S_ISLNK(p->fts_statp->st_mode)) 170253789Srpaulo goto typeerr; 171253789Srpaulo break; 172253789Srpaulo#ifdef S_ISSOCK 173253789Srpaulo case F_SOCK: 174253789Srpaulo if (!S_ISSOCK(p->fts_statp->st_mode)) 175253789Srpaulo goto typeerr; 176253789Srpaulo break; 177253789Srpaulo#endif 178253789Srpaulotypeerr: LABEL; 179253789Srpaulo printf(flavor == F_FREEBSD9 ? 180253789Srpaulo "\ttype expected %s found %s\n" : "\ttype (%s, %s)\n", 181253789Srpaulo nodetype(s->type), inotype(p->fts_statp->st_mode)); 182253789Srpaulo return (label); 183253789Srpaulo } 184253789Srpaulo if (mtree_Wflag) 185253789Srpaulo goto afterpermwhack; 186253789Srpaulo#if HAVE_STRUCT_STAT_ST_FLAGS 187253789Srpaulo if (iflag && !uflag) { 188253789Srpaulo if (s->flags & F_FLAGS) 189253789Srpaulo SETFLAGS(p->fts_statp->st_flags, SP_FLGS); 190253789Srpaulo return (label); 191253789Srpaulo } 192253789Srpaulo if (mflag && !uflag) { 193266577Shselasky if (s->flags & F_FLAGS) 194253789Srpaulo CLEARFLAGS(p->fts_statp->st_flags, SP_FLGS); 195253789Srpaulo return (label); 196253789Srpaulo } 197253789Srpaulo#endif 198253789Srpaulo if (s->flags & F_DEV && 199253789Srpaulo (s->type == F_BLOCK || s->type == F_CHAR) && 200253789Srpaulo s->st_rdev != p->fts_statp->st_rdev) { 201253789Srpaulo LABEL; 202253789Srpaulo printf(flavor == F_FREEBSD9 ? 203253789Srpaulo "%sdevice expected %#jx found %#jx" : 204253789Srpaulo "%sdevice (%#jx, %#jx", 205253789Srpaulo tab, (uintmax_t)s->st_rdev, 206253789Srpaulo (uintmax_t)p->fts_statp->st_rdev); 207253789Srpaulo if (uflag) { 208253789Srpaulo if ((unlink(p->fts_accpath) == -1) || 209253789Srpaulo (mknod(p->fts_accpath, 210253789Srpaulo s->st_mode | nodetoino(s->type), 211253789Srpaulo s->st_rdev) == -1) || 212253789Srpaulo (lchown(p->fts_accpath, p->fts_statp->st_uid, 213253789Srpaulo p->fts_statp->st_gid) == -1) ) 214253789Srpaulo printf(", not modified: %s%s\n", 215253789Srpaulo strerror(errno), 216253789Srpaulo flavor == F_FREEBSD9 ? "" : ")"); 217267349Shselasky else 218267349Shselasky printf(", modified%s\n", 219267349Shselasky flavor == F_FREEBSD9 ? "" : ")"); 220267349Shselasky } else 221267349Shselasky printf(")\n"); 222267349Shselasky tab = "\t"; 223267349Shselasky } 224253789Srpaulo /* Set the uid/gid first, then set the mode. */ 225253789Srpaulo if (s->flags & (F_UID | F_UNAME) && s->st_uid != p->fts_statp->st_uid) { 226253789Srpaulo LABEL; 227253789Srpaulo printf(flavor == F_FREEBSD9 ? 228253789Srpaulo "%suser expected %lu found %lu" : "%suser (%lu, %lu", 229253789Srpaulo tab, (u_long)s->st_uid, (u_long)p->fts_statp->st_uid); 230253789Srpaulo if (uflag) { 231253789Srpaulo if (lchown(p->fts_accpath, s->st_uid, -1)) 232253789Srpaulo printf(", not modified: %s%s\n", 233253789Srpaulo strerror(errno), 234253789Srpaulo flavor == F_FREEBSD9 ? "" : ")"); 235253789Srpaulo else 236267349Shselasky printf(", modified%s\n", 237253789Srpaulo flavor == F_FREEBSD9 ? "" : ")"); 238253789Srpaulo } else 239253789Srpaulo printf(")\n"); 240253789Srpaulo tab = "\t"; 241253789Srpaulo } 242253789Srpaulo if (s->flags & (F_GID | F_GNAME) && s->st_gid != p->fts_statp->st_gid) { 243253789Srpaulo LABEL; 244253789Srpaulo printf(flavor == F_FREEBSD9 ? 245253789Srpaulo "%sgid expected %lu found %lu" : "%sgid (%lu, %lu", 246267349Shselasky tab, (u_long)s->st_gid, (u_long)p->fts_statp->st_gid); 247253789Srpaulo if (uflag) { 248253789Srpaulo if (lchown(p->fts_accpath, -1, s->st_gid)) 249267349Shselasky printf(", not modified: %s%s\n", 250253789Srpaulo strerror(errno), 251253789Srpaulo flavor == F_FREEBSD9 ? "" : ")"); 252253789Srpaulo else 253253789Srpaulo printf(", modified%s\n", 254253789Srpaulo flavor == F_FREEBSD9 ? "" : ")"); 255253789Srpaulo } 256253789Srpaulo else 257253789Srpaulo printf(")\n"); 258253789Srpaulo tab = "\t"; 259267349Shselasky } 260253789Srpaulo if (s->flags & F_MODE && 261253789Srpaulo s->st_mode != (p->fts_statp->st_mode & MBITS)) { 262253789Srpaulo if (lflag) { 263253789Srpaulo mode_t tmode, mode; 264253789Srpaulo 265253789Srpaulo tmode = s->st_mode; 266253789Srpaulo mode = p->fts_statp->st_mode & MBITS; 267253789Srpaulo /* 268253789Srpaulo * if none of the suid/sgid/etc bits are set, 269253789Srpaulo * then if the mode is a subset of the target, 270253789Srpaulo * skip. 271253789Srpaulo */ 272253789Srpaulo if (!((tmode & ~(S_IRWXU|S_IRWXG|S_IRWXO)) || 273253789Srpaulo (mode & ~(S_IRWXU|S_IRWXG|S_IRWXO)))) 274253789Srpaulo if ((mode | tmode) == tmode) 275253789Srpaulo goto skip; 276253789Srpaulo } 277253789Srpaulo 278253789Srpaulo LABEL; 279253789Srpaulo printf(flavor == F_FREEBSD9 ? 280253789Srpaulo "%spermissions expcted %#lo found %#lo" : 281253789Srpaulo "%spermissions (%#lo, %#lo", 282253789Srpaulo tab, (u_long)s->st_mode, 283253789Srpaulo (u_long)p->fts_statp->st_mode & MBITS); 284253789Srpaulo if (uflag) { 285253789Srpaulo if (lchmod(p->fts_accpath, s->st_mode)) 286253789Srpaulo printf(", not modified: %s%s\n", 287253789Srpaulo strerror(errno), 288253789Srpaulo flavor == F_FREEBSD9 ? "" : ")"); 289253789Srpaulo else 290253789Srpaulo printf(", modified%s\n", 291253789Srpaulo flavor == F_FREEBSD9 ? "" : ")"); 292253789Srpaulo } 293253789Srpaulo else 294253789Srpaulo printf(")\n"); 295253789Srpaulo tab = "\t"; 296266577Shselasky skip: ; 297266577Shselasky } 298266577Shselasky if (s->flags & F_NLINK && s->type != F_DIR && 299266577Shselasky s->st_nlink != p->fts_statp->st_nlink) { 300266577Shselasky LABEL; 301266577Shselasky printf(flavor == F_FREEBSD9 ? 302266577Shselasky "%slink count expected %lu found %lu\n" : 303266577Shselasky "%slink count (%lu, %lu)\n", 304266577Shselasky tab, (u_long)s->st_nlink, (u_long)p->fts_statp->st_nlink); 305266577Shselasky tab = "\t"; 306266577Shselasky } 307266577Shselasky if (s->flags & F_SIZE && s->st_size != p->fts_statp->st_size) { 308266577Shselasky LABEL; 309266577Shselasky printf(flavor == F_FREEBSD9 ? 310253789Srpaulo "%ssize expected %ju found %ju\n" : "%ssize (%ju, %ju)\n", 311253789Srpaulo tab, (uintmax_t)s->st_size, 312253789Srpaulo (uintmax_t)p->fts_statp->st_size); 313253789Srpaulo tab = "\t"; 314253789Srpaulo } 315253789Srpaulo /* 316253789Srpaulo * XXX 317253831Srpaulo * Since utimes(2) only takes a timeval, there's no point in 318253789Srpaulo * comparing the low bits of the timespec nanosecond field. This 319253789Srpaulo * will only result in mismatches that we can never fix. 320253789Srpaulo * 321253789Srpaulo * Doesn't display microsecond differences. 322253789Srpaulo */ 323253789Srpaulo if (s->flags & F_TIME) { 324253789Srpaulo struct timeval tv[2]; 325276975Shselasky struct stat *ps = p->fts_statp; 326253789Srpaulo time_t smtime = s->st_mtimespec.tv_sec; 327253789Srpaulo 328253831Srpaulo#if defined(BSD4_4) && !defined(HAVE_NBTOOL_CONFIG_H) 329253789Srpaulo time_t pmtime = ps->st_mtimespec.tv_sec; 330253789Srpaulo 331253789Srpaulo TIMESPEC_TO_TIMEVAL(&tv[0], &s->st_mtimespec); 332253789Srpaulo TIMESPEC_TO_TIMEVAL(&tv[1], &ps->st_mtimespec); 333253789Srpaulo#else 334253789Srpaulo time_t pmtime = (time_t)ps->st_mtime; 335253831Srpaulo 336253789Srpaulo tv[0].tv_sec = smtime; 337253789Srpaulo tv[0].tv_usec = 0; 338253789Srpaulo tv[1].tv_sec = pmtime; 339253789Srpaulo tv[1].tv_usec = 0; 340253789Srpaulo#endif 341253789Srpaulo 342253789Srpaulo if (tv[0].tv_sec != tv[1].tv_sec || 343253789Srpaulo tv[0].tv_usec != tv[1].tv_usec) { 344253789Srpaulo LABEL; 345253789Srpaulo printf(flavor == F_FREEBSD9 ? 346253789Srpaulo "%smodification time expected %.24s found " : 347253789Srpaulo "%smodification time (%.24s, ", 348253789Srpaulo tab, ctime(&smtime)); 349253789Srpaulo printf("%.24s", ctime(&pmtime)); 350253789Srpaulo if (tflag) { 351253789Srpaulo tv[1] = tv[0]; 352253789Srpaulo if (utimes(p->fts_accpath, tv)) 353253789Srpaulo printf(", not modified: %s%s\n", 354253789Srpaulo strerror(errno), 355253789Srpaulo flavor == F_FREEBSD9 ? "" : ")"); 356253789Srpaulo else 357253789Srpaulo printf(", modified%s\n", 358253789Srpaulo flavor == F_FREEBSD9 ? "" : ")"); 359253789Srpaulo } else 360253789Srpaulo printf("%s\n", flavor == F_FREEBSD9 ? "" : ")"); 361253789Srpaulo tab = "\t"; 362253789Srpaulo } 363253789Srpaulo } 364253789Srpaulo#if HAVE_STRUCT_STAT_ST_FLAGS 365253789Srpaulo /* 366253789Srpaulo * XXX 367253789Srpaulo * since lchflags(2) will reset file times, the utimes() above 368253789Srpaulo * may have been useless! oh well, we'd rather have correct 369253789Srpaulo * flags, rather than times? 370253789Srpaulo */ 371253789Srpaulo if ((s->flags & F_FLAGS) && ((s->st_flags != p->fts_statp->st_flags) 372253789Srpaulo || mflag || iflag)) { 373253789Srpaulo if (s->st_flags != p->fts_statp->st_flags) { 374253789Srpaulo char *f_s; 375253789Srpaulo LABEL; 376253789Srpaulo f_s = flags_to_string(s->st_flags, "none"); 377253789Srpaulo printf(flavor == F_FREEBSD9 ? 378253789Srpaulo "%sflags expected \"%s\" found " : 379253789Srpaulo "%sflags (\"%s\" is not ", tab, f_s); 380253789Srpaulo free(f_s); 381253789Srpaulo f_s = flags_to_string(p->fts_statp->st_flags, "none"); 382253789Srpaulo printf("\"%s\"", f_s); 383253789Srpaulo free(f_s); 384253789Srpaulo } 385253789Srpaulo if (uflag) { 386253789Srpaulo if (iflag) 387253789Srpaulo SETFLAGS(0, CH_MASK); 388253789Srpaulo else if (mflag) 389253789Srpaulo CLEARFLAGS(0, SP_FLGS); 390253789Srpaulo else 391253789Srpaulo SETFLAGS(0, (~SP_FLGS & CH_MASK)); 392253789Srpaulo } else 393253789Srpaulo printf("%s\n", flavor == F_FREEBSD9 ? "" : ")"); 394253789Srpaulo tab = "\t"; 395253789Srpaulo } 396253789Srpaulo#endif /* HAVE_STRUCT_STAT_ST_FLAGS */ 397253789Srpaulo 398253789Srpaulo /* 399253789Srpaulo * from this point, no more permission checking or whacking 400253789Srpaulo * occurs, only checking of stuff like checksums and symlinks. 401253831Srpaulo */ 402253831Srpaulo afterpermwhack: 403253831Srpaulo if (s->flags & F_CKSUM) { 404253831Srpaulo if ((fd = open(p->fts_accpath, O_RDONLY, 0)) < 0) { 405253831Srpaulo LABEL; 406253789Srpaulo printf("%scksum: %s: %s\n", 407253789Srpaulo tab, p->fts_accpath, strerror(errno)); 408253789Srpaulo tab = "\t"; 409253789Srpaulo } else if (crc(fd, &val, &len)) { 410253789Srpaulo close(fd); 411253789Srpaulo LABEL; 412253789Srpaulo printf("%scksum: %s: %s\n", 413253789Srpaulo tab, p->fts_accpath, strerror(errno)); 414253789Srpaulo tab = "\t"; 415253789Srpaulo } else { 416253789Srpaulo close(fd); 417253789Srpaulo if (s->cksum != val) { 418253789Srpaulo LABEL; 419253789Srpaulo printf(flavor == F_FREEBSD9 ? 420253789Srpaulo "%scksum expected %lu found %lu\n" : 421253789Srpaulo "%scksum (%lu, %lu)\n", 422253789Srpaulo tab, s->cksum, (unsigned long)val); 423253789Srpaulo } 424253789Srpaulo tab = "\t"; 425253789Srpaulo } 426253789Srpaulo } 427253789Srpaulo#ifndef NO_MD5 428253789Srpaulo if (s->flags & F_MD5) { 429253789Srpaulo if ((digestbuf = MD5File(p->fts_accpath, NULL)) == NULL) { 430253789Srpaulo LABEL; 431253789Srpaulo printf("%s%s: %s: %s\n", 432253789Srpaulo tab, MD5KEY, p->fts_accpath, strerror(errno)); 433253789Srpaulo tab = "\t"; 434253789Srpaulo } else { 435253789Srpaulo if (strcmp(s->md5digest, digestbuf)) { 436253789Srpaulo LABEL; 437253789Srpaulo printf(flavor == F_FREEBSD9 ? 438253789Srpaulo "%s%s expected %s found %s\n" : 439253789Srpaulo "%s%s (0x%s, 0x%s)\n", 440253789Srpaulo tab, MD5KEY, s->md5digest, digestbuf); 441253789Srpaulo } 442253789Srpaulo tab = "\t"; 443253789Srpaulo free(digestbuf); 444266577Shselasky } 445253789Srpaulo } 446253789Srpaulo#endif /* ! NO_MD5 */ 447253789Srpaulo#ifndef NO_RMD160 448253789Srpaulo if (s->flags & F_RMD160) { 449253789Srpaulo if ((digestbuf = RMD160File(p->fts_accpath, NULL)) == NULL) { 450253789Srpaulo LABEL; 451253789Srpaulo printf("%s%s: %s: %s\n", 452253789Srpaulo tab, RMD160KEY, p->fts_accpath, strerror(errno)); 453253789Srpaulo tab = "\t"; 454253789Srpaulo } else { 455253789Srpaulo if (strcmp(s->rmd160digest, digestbuf)) { 456253789Srpaulo LABEL; 457253789Srpaulo printf(flavor == F_FREEBSD9 ? 458253789Srpaulo "%s%s expected %s found %s\n" : 459253789Srpaulo "%s%s (0x%s, 0x%s)\n", 460253789Srpaulo tab, RMD160KEY, s->rmd160digest, digestbuf); 461253789Srpaulo } 462253789Srpaulo tab = "\t"; 463253789Srpaulo free(digestbuf); 464253789Srpaulo } 465253789Srpaulo } 466253789Srpaulo#endif /* ! NO_RMD160 */ 467253789Srpaulo#ifndef NO_SHA1 468253789Srpaulo if (s->flags & F_SHA1) { 469253789Srpaulo if ((digestbuf = SHA1File(p->fts_accpath, NULL)) == NULL) { 470253789Srpaulo LABEL; 471253789Srpaulo printf("%s%s: %s: %s\n", 472259453Shselasky tab, SHA1KEY, p->fts_accpath, strerror(errno)); 473259453Shselasky tab = "\t"; 474259453Shselasky } else { 475259453Shselasky if (strcmp(s->sha1digest, digestbuf)) { 476259453Shselasky LABEL; 477259453Shselasky printf(flavor == F_FREEBSD9 ? 478259453Shselasky "%s%s expected %s found %s\n" : 479253789Srpaulo "%s%s (0x%s, 0x%s)\n", 480253789Srpaulo tab, SHA1KEY, s->sha1digest, digestbuf); 481253789Srpaulo } 482253789Srpaulo tab = "\t"; 483253789Srpaulo free(digestbuf); 484253789Srpaulo } 485253789Srpaulo } 486253789Srpaulo#endif /* ! NO_SHA1 */ 487253789Srpaulo#ifndef NO_SHA2 488253789Srpaulo if (s->flags & F_SHA256) { 489253789Srpaulo if ((digestbuf = SHA256_File(p->fts_accpath, NULL)) == NULL) { 490253789Srpaulo LABEL; 491253789Srpaulo printf("%s%s: %s: %s\n", 492253789Srpaulo tab, SHA256KEY, p->fts_accpath, strerror(errno)); 493253789Srpaulo tab = "\t"; 494253789Srpaulo } else { 495253789Srpaulo if (strcmp(s->sha256digest, digestbuf)) { 496253789Srpaulo LABEL; 497253789Srpaulo printf(flavor == F_FREEBSD9 ? 498253789Srpaulo "%s%s expected %s found %s\n" : 499253789Srpaulo "%s%s (0x%s, 0x%s)\n", 500253789Srpaulo tab, SHA256KEY, s->sha256digest, digestbuf); 501253789Srpaulo } 502253789Srpaulo tab = "\t"; 503253789Srpaulo free(digestbuf); 504253789Srpaulo } 505253789Srpaulo } 506253789Srpaulo#ifdef SHA384_BLOCK_LENGTH 507253789Srpaulo if (s->flags & F_SHA384) { 508253789Srpaulo if ((digestbuf = SHA384_File(p->fts_accpath, NULL)) == NULL) { 509253789Srpaulo LABEL; 510253789Srpaulo printf("%s%s: %s: %s\n", 511253789Srpaulo tab, SHA384KEY, p->fts_accpath, strerror(errno)); 512253789Srpaulo tab = "\t"; 513253789Srpaulo } else { 514253789Srpaulo if (strcmp(s->sha384digest, digestbuf)) { 515253789Srpaulo LABEL; 516253789Srpaulo printf(flavor == F_FREEBSD9 ? 517253789Srpaulo "%s%s expected %s found %s\n" : 518253789Srpaulo "%s%s (0x%s, 0x%s)\n", 519253789Srpaulo tab, SHA384KEY, s->sha384digest, digestbuf); 520253789Srpaulo } 521253789Srpaulo tab = "\t"; 522253789Srpaulo free(digestbuf); 523253789Srpaulo } 524253789Srpaulo } 525253789Srpaulo#endif 526253789Srpaulo if (s->flags & F_SHA512) { 527253789Srpaulo if ((digestbuf = SHA512_File(p->fts_accpath, NULL)) == NULL) { 528253789Srpaulo LABEL; 529253789Srpaulo printf("%s%s: %s: %s\n", 530253789Srpaulo tab, SHA512KEY, p->fts_accpath, strerror(errno)); 531253789Srpaulo tab = "\t"; 532253789Srpaulo } else { 533253789Srpaulo if (strcmp(s->sha512digest, digestbuf)) { 534253789Srpaulo LABEL; 535253789Srpaulo printf(flavor == F_FREEBSD9 ? 536253789Srpaulo "%s%s expected %s found %s\n" : 537253789Srpaulo "%s%s (0x%s, 0x%s)\n", 538253789Srpaulo tab, SHA512KEY, s->sha512digest, digestbuf); 539253789Srpaulo } 540253789Srpaulo tab = "\t"; 541253789Srpaulo free(digestbuf); 542253789Srpaulo } 543253789Srpaulo } 544253789Srpaulo#endif /* ! NO_SHA2 */ 545253789Srpaulo if (s->flags & F_SLINK && 546253789Srpaulo strcmp(cp = rlink(p->fts_accpath), s->slink)) { 547253789Srpaulo LABEL; 548253789Srpaulo printf(flavor == F_FREEBSD9 ? 549253789Srpaulo "%slink ref expected %s found %s" : 550253789Srpaulo "%slink ref (%s, %s", tab, cp, s->slink); 551253789Srpaulo if (uflag) { 552253789Srpaulo if ((unlink(p->fts_accpath) == -1) || 553253789Srpaulo (symlink(s->slink, p->fts_accpath) == -1) ) 554253789Srpaulo printf(", not modified: %s%s\n", 555253789Srpaulo strerror(errno), 556253789Srpaulo flavor == F_FREEBSD9 ? "" : ")"); 557253789Srpaulo else 558253789Srpaulo printf(", modified%s\n", 559253789Srpaulo flavor == F_FREEBSD9 ? "" : ")"); 560253789Srpaulo } else 561253789Srpaulo printf("%s\n", flavor == F_FREEBSD9 ? "" : ")"); 562253789Srpaulo } 563253789Srpaulo return (label); 564253789Srpaulo} 565253789Srpaulo 566253789Srpauloconst char * 567253789Srpaulorlink(const char *name) 568253789Srpaulo{ 569253789Srpaulo static char lbuf[MAXPATHLEN]; 570253789Srpaulo int len; 571253789Srpaulo 572253789Srpaulo if ((len = readlink(name, lbuf, sizeof(lbuf) - 1)) == -1) 573253789Srpaulo mtree_err("%s: %s", name, strerror(errno)); 574253789Srpaulo lbuf[len] = '\0'; 575253789Srpaulo return (lbuf); 576253789Srpaulo} 577253789Srpaulo