1/*-
2 * Copyright (c) 1989, 1990, 1993
3 *	The Regents of the University of California.  All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the University nor the names of its contributors
14 *    may be used to endorse or promote products derived from this software
15 *    without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#if 0
31#ifndef lint
32static const char copyright[] =
33"@(#) Copyright (c) 1989, 1990, 1993\n\
34	The Regents of the University of California.  All rights reserved.\n";
35#endif /* not lint */
36
37#ifndef lint
38static char sccsid[] = "@(#)mtree.c	8.1 (Berkeley) 6/6/93";
39#endif /* not lint */
40#endif
41#include <sys/cdefs.h>
42__FBSDID("$FreeBSD$");
43
44#include <sys/param.h>
45#include <sys/stat.h>
46#include <err.h>
47#include <errno.h>
48#include <fts.h>
49#include <stdio.h>
50#include <unistd.h>
51#include "mtree.h"
52#include "extern.h"
53
54int ftsoptions = FTS_PHYSICAL;
55int dflag, eflag, iflag, nflag, qflag, rflag, sflag, uflag, wflag;
56static int cflag, Uflag;
57u_int keys;
58char fullpath[MAXPATHLEN];
59
60static void usage(void);
61
62int
63main(int argc, char *argv[])
64{
65	int ch;
66	char *dir, *p;
67	int status;
68	FILE *spec1, *spec2;
69
70	dir = NULL;
71	keys = KEYDEFAULT;
72	init_excludes();
73	spec1 = stdin;
74	spec2 = NULL;
75
76	while ((ch = getopt(argc, argv, "cdef:iK:k:LnPp:qrs:UuwxX:")) != -1)
77		switch((char)ch) {
78		case 'c':
79			cflag = 1;
80			break;
81		case 'd':
82			dflag = 1;
83			break;
84		case 'e':
85			eflag = 1;
86			break;
87		case 'f':
88			if (spec1 == stdin) {
89				spec1 = fopen(optarg, "r");
90				if (spec1 == NULL)
91					err(1, "%s", optarg);
92			} else if (spec2 == NULL) {
93				spec2 = fopen(optarg, "r");
94				if (spec2 == NULL)
95					err(1, "%s", optarg);
96			} else
97				usage();
98			break;
99		case 'i':
100			iflag = 1;
101			break;
102		case 'K':
103			while ((p = strsep(&optarg, " \t,")) != NULL)
104				if (*p != '\0')
105					keys |= parsekey(p, NULL);
106			break;
107		case 'k':
108			keys = F_TYPE;
109			while ((p = strsep(&optarg, " \t,")) != NULL)
110				if (*p != '\0')
111					keys |= parsekey(p, NULL);
112			break;
113		case 'L':
114			ftsoptions &= ~FTS_PHYSICAL;
115			ftsoptions |= FTS_LOGICAL;
116			break;
117		case 'n':
118			nflag = 1;
119			break;
120		case 'P':
121			ftsoptions &= ~FTS_LOGICAL;
122			ftsoptions |= FTS_PHYSICAL;
123			break;
124		case 'p':
125			dir = optarg;
126			break;
127		case 'q':
128			qflag = 1;
129			break;
130		case 'r':
131			rflag = 1;
132			break;
133		case 's':
134			sflag = 1;
135			crc_total = ~strtoul(optarg, &p, 0);
136			if (*p)
137				errx(1, "illegal seed value -- %s", optarg);
138			break;
139		case 'U':
140			Uflag = 1;
141			uflag = 1;
142			break;
143		case 'u':
144			uflag = 1;
145			break;
146		case 'w':
147			wflag = 1;
148			break;
149		case 'x':
150			ftsoptions |= FTS_XDEV;
151			break;
152		case 'X':
153			read_excludes_file(optarg);
154			break;
155		case '?':
156		default:
157			usage();
158		}
159	argc -= optind;
160	argv += optind;
161
162	if (argc)
163		usage();
164
165	if (dir && chdir(dir))
166		err(1, "%s", dir);
167
168	if ((cflag || sflag) && !getcwd(fullpath, sizeof(fullpath)))
169		errx(1, "%s", fullpath);
170
171	if (cflag) {
172		cwalk();
173		exit(0);
174	}
175	if (spec2 != NULL)
176		status = mtree_specspec(spec1, spec2);
177	else
178		status = mtree_verifyspec(spec1);
179	if (Uflag & (status == MISMATCHEXIT))
180		status = 0;
181	exit(status);
182}
183
184static void
185usage(void)
186{
187	(void)fprintf(stderr,
188"usage: mtree [-LPUcdeinqruxw] [-f spec] [-f spec] [-K key] [-k key] [-p path] [-s seed]\n"
189"\t[-X excludes]\n");
190	exit(1);
191}
192