verify.c revision 51705
11553Srgrimes/*- 21553Srgrimes * Copyright (c) 1990, 1993 31553Srgrimes * The Regents of the University of California. All rights reserved. 41553Srgrimes * 51553Srgrimes * Redistribution and use in source and binary forms, with or without 61553Srgrimes * modification, are permitted provided that the following conditions 71553Srgrimes * are met: 81553Srgrimes * 1. Redistributions of source code must retain the above copyright 91553Srgrimes * notice, this list of conditions and the following disclaimer. 101553Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111553Srgrimes * notice, this list of conditions and the following disclaimer in the 121553Srgrimes * documentation and/or other materials provided with the distribution. 131553Srgrimes * 3. All advertising materials mentioning features or use of this software 141553Srgrimes * must display the following acknowledgement: 151553Srgrimes * This product includes software developed by the University of 161553Srgrimes * California, Berkeley and its contributors. 171553Srgrimes * 4. Neither the name of the University nor the names of its contributors 181553Srgrimes * may be used to endorse or promote products derived from this software 191553Srgrimes * without specific prior written permission. 201553Srgrimes * 211553Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221553Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231553Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241553Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251553Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261553Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271553Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281553Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291553Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301553Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311553Srgrimes * SUCH DAMAGE. 321553Srgrimes */ 331553Srgrimes 341553Srgrimes#ifndef lint 3530027Scharnier#if 0 361553Srgrimesstatic char sccsid[] = "@(#)verify.c 8.1 (Berkeley) 6/6/93"; 3730027Scharnier#endif 3830027Scharnierstatic const char rcsid[] = 3950479Speter "$FreeBSD: head/usr.sbin/mtree/verify.c 51705 1999-09-27 00:36:03Z billf $"; 401553Srgrimes#endif /* not lint */ 411553Srgrimes 421553Srgrimes#include <sys/param.h> 431553Srgrimes#include <sys/stat.h> 441553Srgrimes#include <dirent.h> 4530027Scharnier#include <err.h> 4630027Scharnier#include <errno.h> 471553Srgrimes#include <fts.h> 481553Srgrimes#include <fnmatch.h> 4930027Scharnier#include <stdio.h> 501553Srgrimes#include <unistd.h> 511553Srgrimes#include "mtree.h" 521553Srgrimes#include "extern.h" 531553Srgrimes 542860Srgrimesextern long int crc_total; 552860Srgrimesextern int ftsoptions; 561553Srgrimesextern int dflag, eflag, rflag, sflag, uflag; 571553Srgrimesextern char fullpath[MAXPATHLEN]; 5830027Scharnierextern int lineno; 591553Srgrimes 601553Srgrimesstatic NODE *root; 611553Srgrimesstatic char path[MAXPATHLEN]; 621553Srgrimes 631553Srgrimesstatic void miss __P((NODE *, char *)); 641553Srgrimesstatic int vwalk __P((void)); 651553Srgrimes 661553Srgrimesint 671553Srgrimesverify() 681553Srgrimes{ 691553Srgrimes int rval; 701553Srgrimes 711553Srgrimes root = spec(); 721553Srgrimes rval = vwalk(); 731553Srgrimes miss(root, path); 741553Srgrimes return (rval); 751553Srgrimes} 761553Srgrimes 771553Srgrimesstatic int 781553Srgrimesvwalk() 791553Srgrimes{ 801553Srgrimes register FTS *t; 811553Srgrimes register FTSENT *p; 821553Srgrimes register NODE *ep, *level; 839675Sbde int specdepth, rval; 841553Srgrimes char *argv[2]; 851553Srgrimes 861553Srgrimes argv[0] = "."; 871553Srgrimes argv[1] = NULL; 881553Srgrimes if ((t = fts_open(argv, ftsoptions, NULL)) == NULL) 8930027Scharnier err(1, "line %d: fts_open", lineno); 901553Srgrimes level = root; 919675Sbde specdepth = rval = 0; 922860Srgrimes while ((p = fts_read(t))) { 931553Srgrimes switch(p->fts_info) { 941553Srgrimes case FTS_D: 951553Srgrimes break; 961553Srgrimes case FTS_DP: 979675Sbde if (specdepth > p->fts_level) { 981553Srgrimes for (level = level->parent; level->prev; 998857Srgrimes level = level->prev); 1001553Srgrimes --specdepth; 1011553Srgrimes } 1021553Srgrimes continue; 1031553Srgrimes case FTS_DNR: 1041553Srgrimes case FTS_ERR: 1051553Srgrimes case FTS_NS: 10630027Scharnier warnx("%s: %s", RP(p), strerror(p->fts_errno)); 1071553Srgrimes continue; 1081553Srgrimes default: 1091553Srgrimes if (dflag) 1101553Srgrimes continue; 1111553Srgrimes } 1121553Srgrimes 1139675Sbde if (specdepth != p->fts_level) 1149675Sbde goto extra; 1151553Srgrimes for (ep = level; ep; ep = ep->next) 1162860Srgrimes if ((ep->flags & F_MAGIC && 1172860Srgrimes !fnmatch(ep->name, p->fts_name, FNM_PATHNAME)) || 1181553Srgrimes !strcmp(ep->name, p->fts_name)) { 1191553Srgrimes ep->flags |= F_VISIT; 12036670Speter if ((ep->flags & F_NOCHANGE) == 0 && 12136670Speter compare(ep->name, ep, p)) 1221553Srgrimes rval = MISMATCHEXIT; 12336841Speter if (ep->flags & F_IGN) 1241553Srgrimes (void)fts_set(t, p, FTS_SKIP); 1251553Srgrimes else if (ep->child && ep->type == F_DIR && 1261553Srgrimes p->fts_info == FTS_D) { 1271553Srgrimes level = ep->child; 1281553Srgrimes ++specdepth; 1291553Srgrimes } 1301553Srgrimes break; 1311553Srgrimes } 1321553Srgrimes 1331553Srgrimes if (ep) 1341553Srgrimes continue; 1359675Sbdeextra: 1361553Srgrimes if (!eflag) { 1371553Srgrimes (void)printf("extra: %s", RP(p)); 1381553Srgrimes if (rflag) { 1399675Sbde if ((S_ISDIR(p->fts_statp->st_mode) 1409675Sbde ? rmdir : unlink)(p->fts_accpath)) { 1411553Srgrimes (void)printf(", not removed: %s", 1421553Srgrimes strerror(errno)); 1431553Srgrimes } else 1441553Srgrimes (void)printf(", removed"); 1451553Srgrimes } 1461553Srgrimes (void)putchar('\n'); 1471553Srgrimes } 1481553Srgrimes (void)fts_set(t, p, FTS_SKIP); 1491553Srgrimes } 1501553Srgrimes (void)fts_close(t); 1511553Srgrimes if (sflag) 15230027Scharnier warnx("%s checksum: %lu", fullpath, crc_total); 1531553Srgrimes return (rval); 1541553Srgrimes} 1551553Srgrimes 1561553Srgrimesstatic void 1571553Srgrimesmiss(p, tail) 1581553Srgrimes register NODE *p; 1591553Srgrimes register char *tail; 1601553Srgrimes{ 1611553Srgrimes register int create; 1621553Srgrimes register char *tp; 1631553Srgrimes 1641553Srgrimes for (; p; p = p->next) { 1651553Srgrimes if (p->type != F_DIR && (dflag || p->flags & F_VISIT)) 1661553Srgrimes continue; 1671553Srgrimes (void)strcpy(tail, p->name); 1681553Srgrimes if (!(p->flags & F_VISIT)) 1691553Srgrimes (void)printf("missing: %s", path); 1701553Srgrimes if (p->type != F_DIR) { 1711553Srgrimes putchar('\n'); 1721553Srgrimes continue; 1731553Srgrimes } 1741553Srgrimes 1751553Srgrimes create = 0; 17651705Sbillf if (!(p->flags & F_VISIT) && uflag) { 1771553Srgrimes if (!(p->flags & (F_UID | F_UNAME))) 17836670Speter (void)printf(" (directory not created: user not specified)"); 1791553Srgrimes else if (!(p->flags & (F_GID | F_GNAME))) 18036670Speter (void)printf(" (directory not created: group not specified)"); 1811553Srgrimes else if (!(p->flags & F_MODE)) 18236670Speter (void)printf(" (directory not created: mode not specified)"); 1831553Srgrimes else if (mkdir(path, S_IRWXU)) 18436670Speter (void)printf(" (directory not created: %s)", 1851553Srgrimes strerror(errno)); 1861553Srgrimes else { 1871553Srgrimes create = 1; 1881553Srgrimes (void)printf(" (created)"); 1891553Srgrimes } 19051705Sbillf } 1911553Srgrimes if (!(p->flags & F_VISIT)) 1921553Srgrimes (void)putchar('\n'); 1931553Srgrimes 1941553Srgrimes for (tp = tail; *tp; ++tp); 1951553Srgrimes *tp = '/'; 1961553Srgrimes miss(p->child, tp + 1); 1971553Srgrimes *tp = '\0'; 1981553Srgrimes 1991553Srgrimes if (!create) 2001553Srgrimes continue; 2011553Srgrimes if (chown(path, p->st_uid, p->st_gid)) { 2021553Srgrimes (void)printf("%s: user/group/mode not modified: %s\n", 2031553Srgrimes path, strerror(errno)); 2041553Srgrimes continue; 2051553Srgrimes } 2061553Srgrimes if (chmod(path, p->st_mode)) 2071553Srgrimes (void)printf("%s: permissions not set: %s\n", 2081553Srgrimes path, strerror(errno)); 2091553Srgrimes } 2101553Srgrimes} 211