1273796Sbrooks/* $NetBSD: mtree.c,v 1.49 2014/04/24 17:22:41 christos Exp $ */ 2244541Sbrooks 3244541Sbrooks/*- 4244541Sbrooks * Copyright (c) 1989, 1990, 1993 5244541Sbrooks * The Regents of the University of California. All rights reserved. 6244541Sbrooks * 7244541Sbrooks * Redistribution and use in source and binary forms, with or without 8244541Sbrooks * modification, are permitted provided that the following conditions 9244541Sbrooks * are met: 10244541Sbrooks * 1. Redistributions of source code must retain the above copyright 11244541Sbrooks * notice, this list of conditions and the following disclaimer. 12244541Sbrooks * 2. Redistributions in binary form must reproduce the above copyright 13244541Sbrooks * notice, this list of conditions and the following disclaimer in the 14244541Sbrooks * documentation and/or other materials provided with the distribution. 15244541Sbrooks * 3. Neither the name of the University nor the names of its contributors 16244541Sbrooks * may be used to endorse or promote products derived from this software 17244541Sbrooks * without specific prior written permission. 18244541Sbrooks * 19244541Sbrooks * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20244541Sbrooks * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21244541Sbrooks * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22244541Sbrooks * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23244541Sbrooks * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24244541Sbrooks * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25244541Sbrooks * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26244541Sbrooks * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27244541Sbrooks * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28244541Sbrooks * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29244541Sbrooks * SUCH DAMAGE. 30244541Sbrooks */ 31244541Sbrooks 32244541Sbrooks#if HAVE_NBTOOL_CONFIG_H 33244541Sbrooks#include "nbtool_config.h" 34244541Sbrooks#endif 35244541Sbrooks 36244541Sbrooks#include <sys/cdefs.h> 37244541Sbrooks#if defined(__COPYRIGHT) && !defined(lint) 38244541Sbrooks__COPYRIGHT("@(#) Copyright (c) 1989, 1990, 1993\ 39244541Sbrooks The Regents of the University of California. All rights reserved."); 40244541Sbrooks#endif /* not lint */ 41244541Sbrooks 42244541Sbrooks#if defined(__RCSID) && !defined(lint) 43244541Sbrooks#if 0 44244541Sbrooksstatic char sccsid[] = "@(#)mtree.c 8.1 (Berkeley) 6/6/93"; 45244541Sbrooks#else 46273796Sbrooks__RCSID("$NetBSD: mtree.c,v 1.49 2014/04/24 17:22:41 christos Exp $"); 47244541Sbrooks#endif 48244541Sbrooks#endif /* not lint */ 49244541Sbrooks 50244541Sbrooks#include <sys/param.h> 51244541Sbrooks#include <sys/stat.h> 52244541Sbrooks 53244541Sbrooks#include <errno.h> 54244541Sbrooks#include <stdio.h> 55244541Sbrooks#include <stdlib.h> 56244541Sbrooks#include <string.h> 57244541Sbrooks#include <unistd.h> 58244541Sbrooks 59244541Sbrooks#include "extern.h" 60244541Sbrooks 61244541Sbrooksint ftsoptions = FTS_PHYSICAL; 62249293Sedint bflag, dflag, eflag, iflag, jflag, lflag, mflag, nflag, qflag, rflag, 63249293Sed sflag, tflag, uflag; 64244541Sbrookschar fullpath[MAXPATHLEN]; 65244541Sbrooks 66244541Sbrooksstatic struct { 67244541Sbrooks enum flavor flavor; 68244541Sbrooks const char name[9]; 69244541Sbrooks} flavors[] = { 70244541Sbrooks {F_MTREE, "mtree"}, 71244541Sbrooks {F_FREEBSD9, "freebsd9"}, 72244541Sbrooks {F_NETBSD6, "netbsd6"}, 73244541Sbrooks}; 74244541Sbrooks 75244541Sbrooks__dead static void usage(void); 76244541Sbrooks 77244541Sbrooksint 78244541Sbrooksmain(int argc, char **argv) 79244541Sbrooks{ 80244541Sbrooks int ch, status; 81244541Sbrooks unsigned int i; 82249293Sed int cflag, Cflag, Dflag, Uflag, wflag; 83244541Sbrooks char *dir, *p; 84244541Sbrooks FILE *spec1, *spec2; 85244541Sbrooks 86244541Sbrooks setprogname(argv[0]); 87244541Sbrooks 88249293Sed cflag = Cflag = Dflag = Uflag = wflag = 0; 89244541Sbrooks dir = NULL; 90244541Sbrooks init_excludes(); 91244541Sbrooks spec1 = stdin; 92244541Sbrooks spec2 = NULL; 93244541Sbrooks 94244541Sbrooks while ((ch = getopt(argc, argv, 95249293Sed "bcCdDeE:f:F:I:ijk:K:lLmMnN:O:p:PqrR:s:StuUwWxX:")) 96244541Sbrooks != -1) { 97244541Sbrooks switch((char)ch) { 98244541Sbrooks case 'b': 99244541Sbrooks bflag = 1; 100244541Sbrooks break; 101244541Sbrooks case 'c': 102244541Sbrooks cflag = 1; 103244541Sbrooks break; 104244541Sbrooks case 'C': 105244541Sbrooks Cflag = 1; 106244541Sbrooks break; 107244541Sbrooks case 'd': 108244541Sbrooks dflag = 1; 109244541Sbrooks break; 110244541Sbrooks case 'D': 111244541Sbrooks Dflag = 1; 112244541Sbrooks break; 113244541Sbrooks case 'E': 114244541Sbrooks parsetags(&excludetags, optarg); 115244541Sbrooks break; 116244541Sbrooks case 'e': 117244541Sbrooks eflag = 1; 118244541Sbrooks break; 119244541Sbrooks case 'f': 120244541Sbrooks if (spec1 == stdin) { 121244541Sbrooks spec1 = fopen(optarg, "r"); 122244541Sbrooks if (spec1 == NULL) 123244541Sbrooks mtree_err("%s: %s", optarg, 124244541Sbrooks strerror(errno)); 125244541Sbrooks } else if (spec2 == NULL) { 126244541Sbrooks spec2 = fopen(optarg, "r"); 127244541Sbrooks if (spec2 == NULL) 128244541Sbrooks mtree_err("%s: %s", optarg, 129244541Sbrooks strerror(errno)); 130244541Sbrooks } else 131244541Sbrooks usage(); 132244541Sbrooks break; 133244541Sbrooks case 'F': 134244541Sbrooks for (i = 0; i < __arraycount(flavors); i++) 135244541Sbrooks if (strcmp(optarg, flavors[i].name) == 0) { 136244541Sbrooks flavor = flavors[i].flavor; 137244541Sbrooks break; 138244541Sbrooks } 139244541Sbrooks if (i == __arraycount(flavors)) 140244541Sbrooks usage(); 141244541Sbrooks break; 142244541Sbrooks case 'i': 143244541Sbrooks iflag = 1; 144244541Sbrooks break; 145244541Sbrooks case 'I': 146244541Sbrooks parsetags(&includetags, optarg); 147244541Sbrooks break; 148244541Sbrooks case 'j': 149244541Sbrooks jflag = 1; 150244541Sbrooks break; 151244541Sbrooks case 'k': 152244541Sbrooks keys = F_TYPE; 153244541Sbrooks while ((p = strsep(&optarg, " \t,")) != NULL) 154244541Sbrooks if (*p != '\0') 155244541Sbrooks keys |= parsekey(p, NULL); 156244541Sbrooks break; 157244541Sbrooks case 'K': 158244541Sbrooks while ((p = strsep(&optarg, " \t,")) != NULL) 159244541Sbrooks if (*p != '\0') 160244541Sbrooks keys |= parsekey(p, NULL); 161244541Sbrooks break; 162244541Sbrooks case 'l': 163244541Sbrooks lflag = 1; 164244541Sbrooks break; 165244541Sbrooks case 'L': 166244541Sbrooks ftsoptions &= ~FTS_PHYSICAL; 167244541Sbrooks ftsoptions |= FTS_LOGICAL; 168244541Sbrooks break; 169244541Sbrooks case 'm': 170244541Sbrooks mflag = 1; 171244541Sbrooks break; 172244541Sbrooks case 'M': 173244541Sbrooks mtree_Mflag = 1; 174244541Sbrooks break; 175244541Sbrooks case 'n': 176244541Sbrooks nflag = 1; 177244541Sbrooks break; 178244541Sbrooks case 'N': 179244541Sbrooks if (! setup_getid(optarg)) 180244541Sbrooks mtree_err( 181244541Sbrooks "Unable to use user and group databases in `%s'", 182244541Sbrooks optarg); 183244541Sbrooks break; 184249293Sed case 'O': 185249293Sed load_only(optarg); 186249293Sed break; 187244541Sbrooks case 'p': 188244541Sbrooks dir = optarg; 189244541Sbrooks break; 190244541Sbrooks case 'P': 191244541Sbrooks ftsoptions &= ~FTS_LOGICAL; 192244541Sbrooks ftsoptions |= FTS_PHYSICAL; 193244541Sbrooks break; 194244541Sbrooks case 'q': 195244541Sbrooks qflag = 1; 196244541Sbrooks break; 197244541Sbrooks case 'r': 198244541Sbrooks rflag = 1; 199244541Sbrooks break; 200244541Sbrooks case 'R': 201244541Sbrooks while ((p = strsep(&optarg, " \t,")) != NULL) 202244541Sbrooks if (*p != '\0') 203244541Sbrooks keys &= ~parsekey(p, NULL); 204244541Sbrooks break; 205244541Sbrooks case 's': 206244541Sbrooks sflag = 1; 207244541Sbrooks crc_total = ~strtol(optarg, &p, 0); 208244541Sbrooks if (*p) 209244541Sbrooks mtree_err("illegal seed value -- %s", optarg); 210244541Sbrooks break; 211244541Sbrooks case 'S': 212244541Sbrooks mtree_Sflag = 1; 213244541Sbrooks break; 214244541Sbrooks case 't': 215244541Sbrooks tflag = 1; 216244541Sbrooks break; 217244541Sbrooks case 'u': 218244541Sbrooks uflag = 1; 219244541Sbrooks break; 220244541Sbrooks case 'U': 221244541Sbrooks Uflag = uflag = 1; 222244541Sbrooks break; 223244541Sbrooks case 'w': 224244541Sbrooks wflag = 1; 225244541Sbrooks break; 226244541Sbrooks case 'W': 227244541Sbrooks mtree_Wflag = 1; 228244541Sbrooks break; 229244541Sbrooks case 'x': 230244541Sbrooks ftsoptions |= FTS_XDEV; 231244541Sbrooks break; 232244541Sbrooks case 'X': 233244541Sbrooks read_excludes_file(optarg); 234244541Sbrooks break; 235244541Sbrooks case '?': 236244541Sbrooks default: 237244541Sbrooks usage(); 238244541Sbrooks } 239244541Sbrooks } 240244541Sbrooks argc -= optind; 241244541Sbrooks argv += optind; 242244541Sbrooks 243244541Sbrooks if (argc) 244244541Sbrooks usage(); 245244541Sbrooks 246244541Sbrooks switch (flavor) { 247244541Sbrooks case F_FREEBSD9: 248244541Sbrooks if (cflag && iflag) { 249244541Sbrooks warnx("-c and -i passed, replacing -i with -j for " 250244541Sbrooks "FreeBSD compatibility"); 251244541Sbrooks iflag = 0; 252244541Sbrooks jflag = 1; 253244541Sbrooks } 254244541Sbrooks if (dflag && !bflag) { 255244541Sbrooks warnx("Adding -b to -d for FreeBSD compatibility"); 256244541Sbrooks bflag = 1; 257244541Sbrooks } 258244541Sbrooks if (uflag && !iflag) { 259244541Sbrooks warnx("Adding -i to -%c for FreeBSD compatibility", 260244541Sbrooks Uflag ? 'U' : 'u'); 261244541Sbrooks iflag = 1; 262244541Sbrooks } 263244541Sbrooks if (uflag && !tflag) { 264244541Sbrooks warnx("Adding -t to -%c for FreeBSD compatibility", 265244541Sbrooks Uflag ? 'U' : 'u'); 266244541Sbrooks tflag = 1; 267244541Sbrooks } 268244541Sbrooks if (wflag) 269244541Sbrooks warnx("The -w flag is a no-op"); 270244541Sbrooks break; 271244541Sbrooks default: 272244541Sbrooks if (wflag) 273244541Sbrooks usage(); 274244541Sbrooks } 275244541Sbrooks 276244541Sbrooks if (spec2 && (cflag || Cflag || Dflag)) 277244541Sbrooks mtree_err("Double -f, -c, -C and -D flags are mutually " 278244541Sbrooks "exclusive"); 279244541Sbrooks 280244541Sbrooks if (dir && spec2) 281244541Sbrooks mtree_err("Double -f and -p flags are mutually exclusive"); 282244541Sbrooks 283244541Sbrooks if (dir && chdir(dir)) 284244541Sbrooks mtree_err("%s: %s", dir, strerror(errno)); 285244541Sbrooks 286244541Sbrooks if ((cflag || sflag) && !getcwd(fullpath, sizeof(fullpath))) 287244541Sbrooks mtree_err("%s", strerror(errno)); 288244541Sbrooks 289244541Sbrooks if ((cflag && Cflag) || (cflag && Dflag) || (Cflag && Dflag)) 290244541Sbrooks mtree_err("-c, -C and -D flags are mutually exclusive"); 291244541Sbrooks 292244541Sbrooks if (iflag && mflag) 293244541Sbrooks mtree_err("-i and -m flags are mutually exclusive"); 294244541Sbrooks 295244541Sbrooks if (lflag && uflag) 296244541Sbrooks mtree_err("-l and -u flags are mutually exclusive"); 297244541Sbrooks 298244541Sbrooks if (cflag) { 299273796Sbrooks cwalk(stdout); 300244541Sbrooks exit(0); 301244541Sbrooks } 302244541Sbrooks if (Cflag || Dflag) { 303273796Sbrooks dump_nodes(stdout, "", spec(spec1), Dflag); 304244541Sbrooks exit(0); 305244541Sbrooks } 306244541Sbrooks if (spec2 != NULL) 307244541Sbrooks status = mtree_specspec(spec1, spec2); 308244541Sbrooks else 309244541Sbrooks status = verify(spec1); 310244541Sbrooks if (Uflag && (status == MISMATCHEXIT)) 311244541Sbrooks status = 0; 312244541Sbrooks exit(status); 313244541Sbrooks} 314244541Sbrooks 315244541Sbrooksstatic void 316244541Sbrooksusage(void) 317244541Sbrooks{ 318244541Sbrooks unsigned int i; 319244541Sbrooks 320244541Sbrooks fprintf(stderr, 321244541Sbrooks "usage: %s [-bCcDdejLlMnPqrStUuWx] [-i|-m] [-E tags]\n" 322244541Sbrooks "\t\t[-f spec] [-f spec]\n" 323244541Sbrooks "\t\t[-I tags] [-K keywords] [-k keywords] [-N dbdir] [-p path]\n" 324244541Sbrooks "\t\t[-R keywords] [-s seed] [-X exclude-file]\n" 325244541Sbrooks "\t\t[-F flavor]\n", 326244541Sbrooks getprogname()); 327244541Sbrooks fprintf(stderr, "\nflavors:"); 328244541Sbrooks for (i = 0; i < __arraycount(flavors); i++) 329244541Sbrooks fprintf(stderr, " %s", flavors[i].name); 330244541Sbrooks fprintf(stderr, "\n"); 331244541Sbrooks exit(1); 332244541Sbrooks} 333