chflags.c revision 102084
1178172Simp/* 2178172Simp * Copyright (c) 1992, 1993, 1994 3178172Simp * The Regents of the University of California. All rights reserved. 4178172Simp * 5178172Simp * Redistribution and use in source and binary forms, with or without 6178172Simp * modification, are permitted provided that the following conditions 7178172Simp * are met: 8178172Simp * 1. Redistributions of source code must retain the above copyright 9178172Simp * notice, this list of conditions and the following disclaimer. 10178172Simp * 2. Redistributions in binary form must reproduce the above copyright 11178172Simp * notice, this list of conditions and the following disclaimer in the 12178172Simp * documentation and/or other materials provided with the distribution. 13178172Simp * 3. All advertising materials mentioning features or use of this software 14178172Simp * must display the following acknowledgement: 15178172Simp * This product includes software developed by the University of 16178172Simp * California, Berkeley and its contributors. 17178172Simp * 4. Neither the name of the University nor the names of its contributors 18178172Simp * may be used to endorse or promote products derived from this software 19178172Simp * without specific prior written permission. 20178172Simp * 21178172Simp * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22178172Simp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23178172Simp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24178172Simp * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25178172Simp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26178172Simp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27178172Simp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28178172Simp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29178172Simp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30178172Simp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31178172Simp * SUCH DAMAGE. 32178172Simp */ 33178172Simp 34178172Simp#ifndef lint 35178172Simpstatic const char copyright[] = 36178172Simp"@(#) Copyright (c) 1992, 1993, 1994\n\ 37202031Simp The Regents of the University of California. All rights reserved.\n"; 38202031Simp#endif 39202031Simp 40202031Simp#if 0 41202031Simp#ifndef lint 42202031Simpstatic char sccsid[] = "@(#)chflags.c 8.5 (Berkeley) 4/1/94"; 43202031Simp#endif 44202031Simp#endif 45202031Simp 46202031Simp#include <sys/cdefs.h> 47202031Simp__FBSDID("$FreeBSD: head/bin/chflags/chflags.c 102084 2002-08-19 03:07:56Z jmallett $"); 48178172Simp 49178172Simp#include <sys/types.h> 50178172Simp#include <sys/stat.h> 51211862Sjchandra 52178172Simp#include <err.h> 53178172Simp#include <errno.h> 54178172Simp#include <fts.h> 55178172Simp#include <stdio.h> 56178172Simp#include <stdlib.h> 57178172Simp#include <string.h> 58178172Simp#include <unistd.h> 59178172Simp 60178172Simpvoid usage(void); 61178172Simp 62178172Simpint 63178172Simpmain(argc, argv) 64178172Simp int argc; 65185427Simp char *argv[]; 66185427Simp{ 67185427Simp FTS *ftsp; 68185427Simp FTSENT *p; 69178172Simp u_long clear, set; 70178172Simp long val; 71178172Simp int Hflag, Lflag, Pflag, Rflag, ch, fts_options, oct, rval; 72178172Simp char *flags, *ep; 73178172Simp 74178172Simp Hflag = Lflag = Pflag = Rflag = 0; 75178172Simp while ((ch = getopt(argc, argv, "HLPR")) != -1) 76178172Simp switch (ch) { 77178172Simp case 'H': 78178172Simp Hflag = 1; 79178172Simp Lflag = Pflag = 0; 80178172Simp break; 81178172Simp case 'L': 82178172Simp Lflag = 1; 83178172Simp Hflag = Pflag = 0; 84178172Simp break; 85178172Simp case 'P': 86178172Simp Pflag = 1; 87178172Simp Hflag = Lflag = 0; 88178172Simp break; 89178172Simp case 'R': 90178172Simp Rflag = 1; 91178172Simp break; 92178172Simp case '?': 93178172Simp default: 94178172Simp usage(); 95178172Simp } 96178172Simp argv += optind; 97178172Simp argc -= optind; 98178172Simp 99178172Simp if (argc < 2) 100178172Simp usage(); 101178172Simp 102178172Simp if (Rflag) { 103178172Simp fts_options = FTS_PHYSICAL; 104178172Simp if (Hflag) 105178172Simp fts_options |= FTS_COMFOLLOW; 106178172Simp if (Lflag) { 107178172Simp fts_options &= ~FTS_PHYSICAL; 108178172Simp fts_options |= FTS_LOGICAL; 109178172Simp } 110178172Simp } else 111178172Simp fts_options = FTS_LOGICAL; 112178172Simp 113178172Simp flags = *argv; 114178172Simp if (*flags >= '0' && *flags <= '7') { 115178172Simp errno = 0; 116178172Simp val = strtol(flags, &ep, 8); 117178172Simp if (val < 0) 118178172Simp errno = ERANGE; 119178172Simp if (errno) 120178172Simp err(1, "invalid flags: %s", flags); 121178172Simp if (*ep) 122178172Simp errx(1, "invalid flags: %s", flags); 123178172Simp set = val; 124178172Simp oct = 1; 125178172Simp } else { 126178172Simp if (strtofflags(&flags, &set, &clear)) 127178172Simp errx(1, "invalid flag: %s", flags); 128178172Simp clear = ~clear; 129178172Simp oct = 0; 130178172Simp } 131178172Simp 132178172Simp if ((ftsp = fts_open(++argv, fts_options , 0)) == NULL) 133178172Simp err(1, NULL); 134178172Simp 135178172Simp for (rval = 0; (p = fts_read(ftsp)) != NULL;) { 136178172Simp switch (p->fts_info) { 137178172Simp case FTS_D: 138178172Simp if (Rflag) /* Change it at FTS_DP. */ 139178172Simp continue; 140202031Simp fts_set(ftsp, p, FTS_SKIP); 141178172Simp break; 142178172Simp case FTS_DNR: /* Warn, chflag, continue. */ 143178172Simp warnx("%s: %s", p->fts_path, strerror(p->fts_errno)); 144178172Simp rval = 1; 145178172Simp break; 146178172Simp case FTS_ERR: /* Warn, continue. */ 147178172Simp case FTS_NS: 148178172Simp warnx("%s: %s", p->fts_path, strerror(p->fts_errno)); 149178172Simp rval = 1; 150178172Simp continue; 151178172Simp case FTS_SL: /* Ignore. */ 152178172Simp case FTS_SLNONE: 153178172Simp /* 154178172Simp * The only symlinks that end up here are ones that 155178172Simp * don't point to anything and ones that we found 156178172Simp * doing a physical walk. 157178172Simp */ 158178172Simp continue; 159178172Simp default: 160178172Simp break; 161178172Simp } 162178172Simp if (oct) { 163178172Simp if (!chflags(p->fts_accpath, set)) 164178172Simp continue; 165178172Simp } else { 166178172Simp p->fts_statp->st_flags |= set; 167178172Simp p->fts_statp->st_flags &= clear; 168178172Simp if (!chflags(p->fts_accpath, (u_long)p->fts_statp->st_flags)) 169178172Simp continue; 170178172Simp } 171178172Simp warn("%s", p->fts_path); 172178172Simp rval = 1; 173178172Simp } 174178172Simp if (errno) 175178172Simp err(1, "fts_read"); 176178172Simp exit(rval); 177178172Simp} 178178172Simp 179178172Simpvoid 180202031Simpusage() 181202031Simp{ 182202031Simp (void)fprintf(stderr, 183202031Simp "usage: chflags [-R [-H | -L | -P]] flags file ...\n"); 184202031Simp exit(1); 185202031Simp} 186202031Simp