xref: /csrg-svn/usr.sbin/mtree/verify.c (revision 61857)
142302Sbostic /*-
2*61857Sbostic  * Copyright (c) 1990, 1993
3*61857Sbostic  *	The Regents of the University of California.  All rights reserved.
442302Sbostic  *
542302Sbostic  * %sccs.include.redist.c%
642302Sbostic  */
742302Sbostic 
842302Sbostic #ifndef lint
9*61857Sbostic static char sccsid[] = "@(#)verify.c	8.1 (Berkeley) 06/06/93";
1042302Sbostic #endif /* not lint */
1142302Sbostic 
1242336Sbostic #include <sys/param.h>
1342302Sbostic #include <sys/stat.h>
1442336Sbostic #include <dirent.h>
1542336Sbostic #include <fts.h>
1654711Sbostic #include <fnmatch.h>
1742337Sbostic #include <unistd.h>
1842302Sbostic #include <errno.h>
1942302Sbostic #include <stdio.h>
2042302Sbostic #include "mtree.h"
2151884Sbostic #include "extern.h"
2242302Sbostic 
2351884Sbostic extern int crc_total, ftsoptions;
2451884Sbostic extern int dflag, eflag, rflag, sflag, uflag;
2551884Sbostic extern char fullpath[MAXPATHLEN];
2642302Sbostic 
2751884Sbostic static NODE *root;
2842336Sbostic static char path[MAXPATHLEN];
2942302Sbostic 
3051884Sbostic static void	miss __P((NODE *, char *));
3151884Sbostic static int	vwalk __P((void));
3251884Sbostic 
3351884Sbostic int
verify()3442302Sbostic verify()
3542302Sbostic {
3651884Sbostic 	int rval;
3751884Sbostic 
3851884Sbostic 	root = spec();
3951884Sbostic 	rval = vwalk();
4042336Sbostic 	miss(root, path);
4151884Sbostic 	return (rval);
4242302Sbostic }
4342302Sbostic 
4451884Sbostic static int
vwalk()4542336Sbostic vwalk()
4642302Sbostic {
4742336Sbostic 	register FTS *t;
4842336Sbostic 	register FTSENT *p;
4942340Sbostic 	register NODE *ep, *level;
5051884Sbostic 	int ftsdepth, specdepth, rval;
5143891Sbostic 	char *argv[2];
5242302Sbostic 
5343891Sbostic 	argv[0] = ".";
5451884Sbostic 	argv[1] = NULL;
5551884Sbostic 	if ((t = fts_open(argv, ftsoptions, NULL)) == NULL)
5651884Sbostic 		err("fts_open: %s", strerror(errno));
5742336Sbostic 	level = root;
5851884Sbostic 	ftsdepth = specdepth = rval = 0;
5945604Sbostic 	while (p = fts_read(t)) {
6042336Sbostic 		switch(p->fts_info) {
6142336Sbostic 		case FTS_D:
6251884Sbostic 			++ftsdepth;
6342336Sbostic 			break;
6442336Sbostic 		case FTS_DP:
6551884Sbostic 			--ftsdepth;
6644864Strent 			if (specdepth > ftsdepth) {
6744864Strent 				for (level = level->parent; level->prev;
6844864Strent 				      level = level->prev);
6951884Sbostic 				--specdepth;
7044864Strent 			}
7142336Sbostic 			continue;
7247239Sbostic 		case FTS_DNR:
7342336Sbostic 		case FTS_ERR:
7447239Sbostic 		case FTS_NS:
7551884Sbostic 			(void)fprintf(stderr, "mtree: %s: %s\n",
7642336Sbostic 			    RP(p), strerror(errno));
7742336Sbostic 			continue;
7842336Sbostic 		default:
7942336Sbostic 			if (dflag)
8042336Sbostic 				continue;
8142302Sbostic 		}
8242336Sbostic 
8342336Sbostic 		for (ep = level; ep; ep = ep->next)
8454711Sbostic 			if (ep->flags & F_MAGIC &&
8554711Sbostic 			    !fnmatch(ep->name, p->fts_name, FNM_PATHNAME) ||
8642337Sbostic 			    !strcmp(ep->name, p->fts_name)) {
8742302Sbostic 				ep->flags |= F_VISIT;
8851884Sbostic 				if (compare(ep->name, ep, p))
8951884Sbostic 					rval = MISMATCHEXIT;
9053191Sbostic 				if (ep->flags & F_IGN)
9153191Sbostic 					(void)fts_set(t, p, FTS_SKIP);
9253191Sbostic 				else if (ep->child && ep->type == F_DIR &&
9344864Strent 				    p->fts_info == FTS_D) {
9442336Sbostic 					level = ep->child;
9551884Sbostic 					++specdepth;
9644864Strent 				}
9742336Sbostic 				break;
9842302Sbostic 			}
9944864Strent 
10042336Sbostic 		if (ep)
10142336Sbostic 			continue;
10242336Sbostic 		if (!eflag) {
10342336Sbostic 			(void)printf("extra: %s", RP(p));
10442336Sbostic 			if (rflag) {
10542336Sbostic 				if (unlink(p->fts_accpath)) {
10642336Sbostic 					(void)printf(", not removed: %s",
10742336Sbostic 					    strerror(errno));
10842336Sbostic 				} else
10942336Sbostic 					(void)printf(", removed");
11042302Sbostic 			}
11142336Sbostic 			(void)putchar('\n');
11242302Sbostic 		}
11345604Sbostic 		(void)fts_set(t, p, FTS_SKIP);
11442302Sbostic 	}
11545604Sbostic 	(void)fts_close(t);
11651884Sbostic 	if (sflag)
11751884Sbostic 		(void)fprintf(stderr,
11851884Sbostic 		    "mtree: %s checksum: %lu\n", fullpath, crc_total);
11951884Sbostic 	return (rval);
12042302Sbostic }
12142302Sbostic 
12251884Sbostic static void
miss(p,tail)12342336Sbostic miss(p, tail)
12442340Sbostic 	register NODE *p;
12542302Sbostic 	register char *tail;
12642302Sbostic {
12742302Sbostic 	register int create;
12842336Sbostic 	register char *tp;
12942302Sbostic 
13042336Sbostic 	for (; p; p = p->next) {
13142340Sbostic 		if (p->type != F_DIR && (dflag || p->flags & F_VISIT))
13242302Sbostic 			continue;
13342336Sbostic 		(void)strcpy(tail, p->name);
13442340Sbostic 		if (!(p->flags & F_VISIT))
13542336Sbostic 			(void)printf("missing: %s", path);
13642340Sbostic 		if (p->type != F_DIR) {
13742336Sbostic 			putchar('\n');
13842336Sbostic 			continue;
13942336Sbostic 		}
14042336Sbostic 
14142302Sbostic 		create = 0;
14242340Sbostic 		if (!(p->flags & F_VISIT) && uflag)
14351884Sbostic 			if (!(p->flags & (F_UID | F_UNAME)))
14451884Sbostic 			    (void)printf(" (not created: user not specified)");
14551884Sbostic 			else if (!(p->flags & (F_GID | F_GNAME)))
14651884Sbostic 			    (void)printf(" (not created: group not specified)");
14751884Sbostic 			else if (!(p->flags & F_MODE))
14851884Sbostic 			    (void)printf(" (not created: mode not specified)");
14942336Sbostic 			else if (mkdir(path, S_IRWXU))
15042336Sbostic 				(void)printf(" (not created: %s)",
15142302Sbostic 				    strerror(errno));
15242302Sbostic 			else {
15342302Sbostic 				create = 1;
15442336Sbostic 				(void)printf(" (created)");
15542302Sbostic 			}
15642302Sbostic 
15742340Sbostic 		if (!(p->flags & F_VISIT))
15842336Sbostic 			(void)putchar('\n');
15942302Sbostic 
16042336Sbostic 		for (tp = tail; *tp; ++tp);
16142336Sbostic 		*tp = '/';
16242336Sbostic 		miss(p->child, tp + 1);
16342336Sbostic 		*tp = '\0';
16442336Sbostic 
16542336Sbostic 		if (!create)
16642336Sbostic 			continue;
16742340Sbostic 		if (chown(path, p->st_uid, p->st_gid)) {
16851884Sbostic 			(void)printf("%s: user/group/mode not modified: %s\n",
16942336Sbostic 			    path, strerror(errno));
17042336Sbostic 			continue;
17142336Sbostic 		}
17242340Sbostic 		if (chmod(path, p->st_mode))
17342336Sbostic 			(void)printf("%s: permissions not set: %s\n",
17442336Sbostic 			    path, strerror(errno));
17542302Sbostic 	}
17642302Sbostic }
177