mtree.c revision 244541
1244541Sbrooks/* $NetBSD: mtree.c,v 1.46 2012/12/20 19:09:25 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 46244541Sbrooks__RCSID("$NetBSD: mtree.c,v 1.46 2012/12/20 19:09:25 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; 62244541Sbrooksint bflag, cflag, Cflag, dflag, Dflag, eflag, iflag, jflag, lflag, mflag, 63244541Sbrooks nflag, qflag, rflag, sflag, tflag, uflag, Uflag, wflag; 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; 82244541Sbrooks char *dir, *p; 83244541Sbrooks FILE *spec1, *spec2; 84244541Sbrooks 85244541Sbrooks setprogname(argv[0]); 86244541Sbrooks 87244541Sbrooks dir = NULL; 88244541Sbrooks init_excludes(); 89244541Sbrooks spec1 = stdin; 90244541Sbrooks spec2 = NULL; 91244541Sbrooks 92244541Sbrooks while ((ch = getopt(argc, argv, 93244541Sbrooks "bcCdDeE:f:F:I:ijk:K:lLmMnN:p:PqrR:s:StuUwWxX:")) 94244541Sbrooks != -1) { 95244541Sbrooks switch((char)ch) { 96244541Sbrooks case 'b': 97244541Sbrooks bflag = 1; 98244541Sbrooks break; 99244541Sbrooks case 'c': 100244541Sbrooks cflag = 1; 101244541Sbrooks break; 102244541Sbrooks case 'C': 103244541Sbrooks Cflag = 1; 104244541Sbrooks break; 105244541Sbrooks case 'd': 106244541Sbrooks dflag = 1; 107244541Sbrooks break; 108244541Sbrooks case 'D': 109244541Sbrooks Dflag = 1; 110244541Sbrooks break; 111244541Sbrooks case 'E': 112244541Sbrooks parsetags(&excludetags, optarg); 113244541Sbrooks break; 114244541Sbrooks case 'e': 115244541Sbrooks eflag = 1; 116244541Sbrooks break; 117244541Sbrooks case 'f': 118244541Sbrooks if (spec1 == stdin) { 119244541Sbrooks spec1 = fopen(optarg, "r"); 120244541Sbrooks if (spec1 == NULL) 121244541Sbrooks mtree_err("%s: %s", optarg, 122244541Sbrooks strerror(errno)); 123244541Sbrooks } else if (spec2 == NULL) { 124244541Sbrooks spec2 = fopen(optarg, "r"); 125244541Sbrooks if (spec2 == NULL) 126244541Sbrooks mtree_err("%s: %s", optarg, 127244541Sbrooks strerror(errno)); 128244541Sbrooks } else 129244541Sbrooks usage(); 130244541Sbrooks break; 131244541Sbrooks case 'F': 132244541Sbrooks for (i = 0; i < __arraycount(flavors); i++) 133244541Sbrooks if (strcmp(optarg, flavors[i].name) == 0) { 134244541Sbrooks flavor = flavors[i].flavor; 135244541Sbrooks break; 136244541Sbrooks } 137244541Sbrooks if (i == __arraycount(flavors)) 138244541Sbrooks usage(); 139244541Sbrooks break; 140244541Sbrooks case 'i': 141244541Sbrooks iflag = 1; 142244541Sbrooks break; 143244541Sbrooks case 'I': 144244541Sbrooks parsetags(&includetags, optarg); 145244541Sbrooks break; 146244541Sbrooks case 'j': 147244541Sbrooks jflag = 1; 148244541Sbrooks break; 149244541Sbrooks case 'k': 150244541Sbrooks keys = F_TYPE; 151244541Sbrooks while ((p = strsep(&optarg, " \t,")) != NULL) 152244541Sbrooks if (*p != '\0') 153244541Sbrooks keys |= parsekey(p, NULL); 154244541Sbrooks break; 155244541Sbrooks case 'K': 156244541Sbrooks while ((p = strsep(&optarg, " \t,")) != NULL) 157244541Sbrooks if (*p != '\0') 158244541Sbrooks keys |= parsekey(p, NULL); 159244541Sbrooks break; 160244541Sbrooks case 'l': 161244541Sbrooks lflag = 1; 162244541Sbrooks break; 163244541Sbrooks case 'L': 164244541Sbrooks ftsoptions &= ~FTS_PHYSICAL; 165244541Sbrooks ftsoptions |= FTS_LOGICAL; 166244541Sbrooks break; 167244541Sbrooks case 'm': 168244541Sbrooks mflag = 1; 169244541Sbrooks break; 170244541Sbrooks case 'M': 171244541Sbrooks mtree_Mflag = 1; 172244541Sbrooks break; 173244541Sbrooks case 'n': 174244541Sbrooks nflag = 1; 175244541Sbrooks break; 176244541Sbrooks case 'N': 177244541Sbrooks if (! setup_getid(optarg)) 178244541Sbrooks mtree_err( 179244541Sbrooks "Unable to use user and group databases in `%s'", 180244541Sbrooks optarg); 181244541Sbrooks break; 182244541Sbrooks case 'p': 183244541Sbrooks dir = optarg; 184244541Sbrooks break; 185244541Sbrooks case 'P': 186244541Sbrooks ftsoptions &= ~FTS_LOGICAL; 187244541Sbrooks ftsoptions |= FTS_PHYSICAL; 188244541Sbrooks break; 189244541Sbrooks case 'q': 190244541Sbrooks qflag = 1; 191244541Sbrooks break; 192244541Sbrooks case 'r': 193244541Sbrooks rflag = 1; 194244541Sbrooks break; 195244541Sbrooks case 'R': 196244541Sbrooks while ((p = strsep(&optarg, " \t,")) != NULL) 197244541Sbrooks if (*p != '\0') 198244541Sbrooks keys &= ~parsekey(p, NULL); 199244541Sbrooks break; 200244541Sbrooks case 's': 201244541Sbrooks sflag = 1; 202244541Sbrooks crc_total = ~strtol(optarg, &p, 0); 203244541Sbrooks if (*p) 204244541Sbrooks mtree_err("illegal seed value -- %s", optarg); 205244541Sbrooks break; 206244541Sbrooks case 'S': 207244541Sbrooks mtree_Sflag = 1; 208244541Sbrooks break; 209244541Sbrooks case 't': 210244541Sbrooks tflag = 1; 211244541Sbrooks break; 212244541Sbrooks case 'u': 213244541Sbrooks uflag = 1; 214244541Sbrooks break; 215244541Sbrooks case 'U': 216244541Sbrooks Uflag = uflag = 1; 217244541Sbrooks break; 218244541Sbrooks case 'w': 219244541Sbrooks wflag = 1; 220244541Sbrooks break; 221244541Sbrooks case 'W': 222244541Sbrooks mtree_Wflag = 1; 223244541Sbrooks break; 224244541Sbrooks case 'x': 225244541Sbrooks ftsoptions |= FTS_XDEV; 226244541Sbrooks break; 227244541Sbrooks case 'X': 228244541Sbrooks read_excludes_file(optarg); 229244541Sbrooks break; 230244541Sbrooks case '?': 231244541Sbrooks default: 232244541Sbrooks usage(); 233244541Sbrooks } 234244541Sbrooks } 235244541Sbrooks argc -= optind; 236244541Sbrooks argv += optind; 237244541Sbrooks 238244541Sbrooks if (argc) 239244541Sbrooks usage(); 240244541Sbrooks 241244541Sbrooks switch (flavor) { 242244541Sbrooks case F_FREEBSD9: 243244541Sbrooks if (cflag && iflag) { 244244541Sbrooks warnx("-c and -i passed, replacing -i with -j for " 245244541Sbrooks "FreeBSD compatibility"); 246244541Sbrooks iflag = 0; 247244541Sbrooks jflag = 1; 248244541Sbrooks } 249244541Sbrooks if (dflag && !bflag) { 250244541Sbrooks warnx("Adding -b to -d for FreeBSD compatibility"); 251244541Sbrooks bflag = 1; 252244541Sbrooks } 253244541Sbrooks if (uflag && !iflag) { 254244541Sbrooks warnx("Adding -i to -%c for FreeBSD compatibility", 255244541Sbrooks Uflag ? 'U' : 'u'); 256244541Sbrooks iflag = 1; 257244541Sbrooks } 258244541Sbrooks if (uflag && !tflag) { 259244541Sbrooks warnx("Adding -t to -%c for FreeBSD compatibility", 260244541Sbrooks Uflag ? 'U' : 'u'); 261244541Sbrooks tflag = 1; 262244541Sbrooks } 263244541Sbrooks if (wflag) 264244541Sbrooks warnx("The -w flag is a no-op"); 265244541Sbrooks break; 266244541Sbrooks default: 267244541Sbrooks if (wflag) 268244541Sbrooks usage(); 269244541Sbrooks } 270244541Sbrooks 271244541Sbrooks if (spec2 && (cflag || Cflag || Dflag)) 272244541Sbrooks mtree_err("Double -f, -c, -C and -D flags are mutually " 273244541Sbrooks "exclusive"); 274244541Sbrooks 275244541Sbrooks if (dir && spec2) 276244541Sbrooks mtree_err("Double -f and -p flags are mutually exclusive"); 277244541Sbrooks 278244541Sbrooks if (dir && chdir(dir)) 279244541Sbrooks mtree_err("%s: %s", dir, strerror(errno)); 280244541Sbrooks 281244541Sbrooks if ((cflag || sflag) && !getcwd(fullpath, sizeof(fullpath))) 282244541Sbrooks mtree_err("%s", strerror(errno)); 283244541Sbrooks 284244541Sbrooks if ((cflag && Cflag) || (cflag && Dflag) || (Cflag && Dflag)) 285244541Sbrooks mtree_err("-c, -C and -D flags are mutually exclusive"); 286244541Sbrooks 287244541Sbrooks if (iflag && mflag) 288244541Sbrooks mtree_err("-i and -m flags are mutually exclusive"); 289244541Sbrooks 290244541Sbrooks if (lflag && uflag) 291244541Sbrooks mtree_err("-l and -u flags are mutually exclusive"); 292244541Sbrooks 293244541Sbrooks if (cflag) { 294244541Sbrooks cwalk(); 295244541Sbrooks exit(0); 296244541Sbrooks } 297244541Sbrooks if (Cflag || Dflag) { 298244541Sbrooks dump_nodes("", spec(spec1), Dflag); 299244541Sbrooks exit(0); 300244541Sbrooks } 301244541Sbrooks if (spec2 != NULL) 302244541Sbrooks status = mtree_specspec(spec1, spec2); 303244541Sbrooks else 304244541Sbrooks status = verify(spec1); 305244541Sbrooks if (Uflag && (status == MISMATCHEXIT)) 306244541Sbrooks status = 0; 307244541Sbrooks exit(status); 308244541Sbrooks} 309244541Sbrooks 310244541Sbrooksstatic void 311244541Sbrooksusage(void) 312244541Sbrooks{ 313244541Sbrooks unsigned int i; 314244541Sbrooks 315244541Sbrooks fprintf(stderr, 316244541Sbrooks "usage: %s [-bCcDdejLlMnPqrStUuWx] [-i|-m] [-E tags]\n" 317244541Sbrooks "\t\t[-f spec] [-f spec]\n" 318244541Sbrooks "\t\t[-I tags] [-K keywords] [-k keywords] [-N dbdir] [-p path]\n" 319244541Sbrooks "\t\t[-R keywords] [-s seed] [-X exclude-file]\n" 320244541Sbrooks "\t\t[-F flavor]\n", 321244541Sbrooks getprogname()); 322244541Sbrooks fprintf(stderr, "\nflavors:"); 323244541Sbrooks for (i = 0; i < __arraycount(flavors); i++) 324244541Sbrooks fprintf(stderr, " %s", flavors[i].name); 325244541Sbrooks fprintf(stderr, "\n"); 326244541Sbrooks exit(1); 327244541Sbrooks} 328