11573Srgrimes/*- 250476Speter * Copyright (c) 1992, 1993, 1994 3156813Sru * The Regents of the University of California. All rights reserved. 4156837Sru * 5156837Sru * Redistribution and use in source and binary forms, with or without 6156813Sru * modification, are permitted provided that the following conditions 7156813Sru * are met: 8211822Snwhitehorn * 1. Redistributions of source code must retain the above copyright 9211822Snwhitehorn * notice, this list of conditions and the following disclaimer. 10211822Snwhitehorn * 2. Redistributions in binary form must reproduce the above copyright 11211822Snwhitehorn * notice, this list of conditions and the following disclaimer in the 12211822Snwhitehorn * documentation and/or other materials provided with the distribution. 13211774Simp * 4. Neither the name of the University nor the names of its contributors 14211774Simp * may be used to endorse or promote products derived from this software 15211778Simp * without specific prior written permission. 16211774Simp * 17211774Simp * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 1893048Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 191573Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2093253Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21123440Sbde * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22123440Sbde * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23123440Sbde * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 241573Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25158794Sume * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26251668Sjlh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27124723Snectar * SUCH DAMAGE. 28117120Sru */ 29211774Simp 30235720Sgleb#if 0 31189765Sgabor#ifndef lint 32235720Sglebstatic const char copyright[] = 331573Srgrimes"@(#) Copyright (c) 1992, 1993, 1994\n\ 34136910Sru The Regents of the University of California. All rights reserved.\n"; 35136910Sru#endif 361573Srgrimes 37213153Sdavidxu#ifndef lint 38213153Sdavidxustatic char sccsid[] = "@(#)chflags.c 8.5 (Berkeley) 4/1/94"; 39213153Sdavidxu#endif 40213153Sdavidxu#endif 41213153Sdavidxu 42169720Skan#include <sys/cdefs.h> 43169720Skan__FBSDID("$FreeBSD: releng/10.3/bin/chflags/chflags.c 283875 2015-06-01 09:04:57Z smh $"); 44169720Skan 45172401Sru#include <sys/types.h> 46169771Skan#include <sys/stat.h> 47235653Smarcel 48169720Skan#include <err.h> 49235653Smarcel#include <errno.h> 50235653Smarcel#include <fcntl.h> 51235653Smarcel#include <fts.h> 52235653Smarcel#include <stdio.h> 53258750Sgjb#include <stdlib.h> 54258750Sgjb#include <string.h> 55258750Sgjb#include <unistd.h> 56107052Sru 57107052Srustatic void usage(void); 58107052Sru 59107052Sruint 60107052Srumain(int argc, char *argv[]) 61107052Sru{ 62107052Sru FTS *ftsp; 63107052Sru FTSENT *p; 64211774Simp u_long clear, newflags, set; 65107052Sru long val; 66107052Sru int Hflag, Lflag, Rflag, fflag, hflag, vflag; 67112202Sobrien int ch, fts_options, oct, rval; 68107052Sru char *flags, *ep; 69107052Sru 70219019Sgabor Hflag = Lflag = Rflag = fflag = hflag = vflag = 0; 71219019Sgabor while ((ch = getopt(argc, argv, "HLPRfhv")) != -1) 72219019Sgabor switch (ch) { 73156960Sume case 'H': 74156960Sume Hflag = 1; 75107052Sru Lflag = 0; 76156960Sume break; 77107052Sru case 'L': 78107052Sru Lflag = 1; 79107052Sru Hflag = 0; 80211774Simp break; 81211774Simp case 'P': 82211774Simp Hflag = Lflag = 0; 83211774Simp break; 84217942Sjchandra case 'R': 85217123Simp Rflag = 1; 86107052Sru break; 87107052Sru case 'f': 88107052Sru fflag = 1; 89156960Sume break; 90107052Sru case 'h': 91107052Sru hflag = 1; 92234370Sjasone break; 93107052Sru case 'v': 94107052Sru vflag++; 95107052Sru break; 96107052Sru case '?': 97107052Sru default: 98107052Sru usage(); 99211774Simp } 100129202Scognet argv += optind; 101129202Scognet argc -= optind; 102156813Sru 103107052Sru if (argc < 2) 104107052Sru usage(); 105107052Sru 106255219Spjd if (Rflag) { 107156813Sru if (hflag) 108107052Sru errx(1, "the -R and -h options may not be " 109107052Sru "specified together."); 110156813Sru if (Lflag) { 111128820Sdas fts_options = FTS_LOGICAL; 112128820Sdas } else { 113158115Sume fts_options = FTS_PHYSICAL; 114158115Sume 115158115Sume if (Hflag) { 116167199Ssimon fts_options |= FTS_COMFOLLOW; 117167199Ssimon } 118167199Ssimon } 119107052Sru } else if (hflag) { 120258750Sgjb fts_options = FTS_PHYSICAL; 121258750Sgjb } else { 122156773Sdeischen fts_options = FTS_LOGICAL; 123156773Sdeischen } 124156773Sdeischen 125156773Sdeischen flags = *argv; 126107052Sru if (*flags >= '0' && *flags <= '7') { 127107052Sru errno = 0; 128107052Sru val = strtol(flags, &ep, 8); 129107052Sru if (val < 0) 130107052Sru errno = ERANGE; 131107052Sru if (errno) 132107052Sru err(1, "invalid flags: %s", flags); 133107052Sru if (*ep) 134107052Sru errx(1, "invalid flags: %s", flags); 135107052Sru set = val; 136107052Sru oct = 1; 137107052Sru } else { 138107052Sru if (strtofflags(&flags, &set, &clear)) 139107052Sru errx(1, "invalid flag: %s", flags); 140107052Sru clear = ~clear; 1411573Srgrimes oct = 0; 1421573Srgrimes } 1431573Srgrimes 144229368Sed if ((ftsp = fts_open(++argv, fts_options , 0)) == NULL) 145229368Sed err(1, NULL); 1461573Srgrimes 147211774Simp for (rval = 0; (p = fts_read(ftsp)) != NULL;) { 1481573Srgrimes int atflag; 1491573Srgrimes 15026047Sasami if ((fts_options & FTS_LOGICAL) || 1511573Srgrimes ((fts_options & FTS_COMFOLLOW) && 152211774Simp p->fts_level == FTS_ROOTLEVEL)) 1531573Srgrimes atflag = 0; 154211774Simp else 1551573Srgrimes atflag = AT_SYMLINK_NOFOLLOW; 156211704Skib 1571573Srgrimes switch (p->fts_info) { 158124374Sru case FTS_D: /* Change it at FTS_DP if we're recursive. */ 159124374Sru if (!Rflag) 160210731Srpaulo fts_set(ftsp, p, FTS_SKIP); 161180012Sru continue; 162180012Sru case FTS_DNR: /* Warn, chflags. */ 163180012Sru warnx("%s: %s", p->fts_path, strerror(p->fts_errno)); 164180012Sru rval = 1; 165180012Sru break; 166180012Sru case FTS_ERR: /* Warn, continue. */ 167213153Sdavidxu case FTS_NS: 168213153Sdavidxu warnx("%s: %s", p->fts_path, strerror(p->fts_errno)); 169 rval = 1; 170 continue; 171 default: 172 break; 173 } 174 if (oct) 175 newflags = set; 176 else 177 newflags = (p->fts_statp->st_flags | set) & clear; 178 if (newflags == p->fts_statp->st_flags) 179 continue; 180 if (chflagsat(AT_FDCWD, p->fts_accpath, newflags, 181 atflag) == -1 && !fflag) { 182 warn("%s", p->fts_path); 183 rval = 1; 184 } else if (vflag) { 185 (void)printf("%s", p->fts_path); 186 if (vflag > 1) 187 (void)printf(": 0%lo -> 0%lo", 188 (u_long)p->fts_statp->st_flags, 189 newflags); 190 (void)printf("\n"); 191 } 192 } 193 if (errno) 194 err(1, "fts_read"); 195 exit(rval); 196} 197 198static void 199usage(void) 200{ 201 (void)fprintf(stderr, 202 "usage: chflags [-fhv] [-R [-H | -L | -P]] flags file ...\n"); 203 exit(1); 204} 205