13839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o/* 23839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * chattr.c - Change file attributes on an ext2 file system 33839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * 43839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * Copyright (C) 1993, 1994 Remy Card <card@masi.ibp.fr> 53839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * Laboratoire MASI, Institut Blaise Pascal 63839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * Universite Pierre et Marie Curie (Paris VI) 73839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * 83839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * This file can be redistributed under the terms of the GNU General 93839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * Public License 103839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */ 113839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 123839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o/* 133839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * History: 143839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * 93/10/30 - Creation 153839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * 93/11/13 - Replace stat() calls by lstat() to avoid loops 163839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * 94/02/27 - Integrated in Ted's distribution 17a88fa0c0135307288562d4922438ae52fdbad855Theodore Ts'o * 98/12/29 - Ignore symlinks when working recursively (G M Sipe) 18a88fa0c0135307288562d4922438ae52fdbad855Theodore Ts'o * 98/12/29 - Display version info only when -V specified (G M Sipe) 193839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */ 203839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 21fff18b4e76d3757a78e5583010bbce3772461f4dTheodore Ts'o#define _LARGEFILE64_SOURCE 22fff18b4e76d3757a78e5583010bbce3772461f4dTheodore Ts'o 23d1154eb460efe588eaed3d439c1caaca149fa362Theodore Ts'o#include "config.h" 24a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o#include <sys/types.h> 253839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <dirent.h> 263839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <fcntl.h> 273839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <stdio.h> 283839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <stdlib.h> 293839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <unistd.h> 3019c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o#include <string.h> 31a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o#ifdef HAVE_ERRNO_H 32a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o#include <errno.h> 33a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o#endif 343839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <sys/param.h> 353839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <sys/stat.h> 3654c637d4d29af3e6365779f8b12976abe95a4753Theodore Ts'o#include "ext2fs/ext2_fs.h" 373839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 38544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o#ifdef __GNUC__ 39544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o#define EXT2FS_ATTR(x) __attribute__(x) 40544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o#else 41544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o#define EXT2FS_ATTR(x) 42544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o#endif 43544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o 4436caf25f8d61eb8ffddc9895463bce5807e96808Theodore Ts'o#ifndef S_ISLNK /* So we can compile even with gcc-warn */ 4536caf25f8d61eb8ffddc9895463bce5807e96808Theodore Ts'o# ifdef __S_IFLNK 4636caf25f8d61eb8ffddc9895463bce5807e96808Theodore Ts'o# define S_ISLNK(mode) __S_ISTYPE((mode), __S_IFLNK) 4736caf25f8d61eb8ffddc9895463bce5807e96808Theodore Ts'o# else 4836caf25f8d61eb8ffddc9895463bce5807e96808Theodore Ts'o# define S_ISLNK(mode) 0 4936caf25f8d61eb8ffddc9895463bce5807e96808Theodore Ts'o# endif 5036caf25f8d61eb8ffddc9895463bce5807e96808Theodore Ts'o#endif 5136caf25f8d61eb8ffddc9895463bce5807e96808Theodore Ts'o 523839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include "et/com_err.h" 533839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include "e2p/e2p.h" 5499ceb8ec1acd7f38da289966b9984b3ffa1914a9Theodore Ts'o#include "support/nls-enable.h" 553839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 563839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include "../version.h" 573839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 58e1a0a3e304229a625c37f0e845c0c9fff117c8c1Theodore Ts'ostatic const char * program_name = "chattr"; 593839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 609a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'ostatic int add; 619a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'ostatic int rem; 629a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'ostatic int set; 639a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'ostatic int set_version; 643839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 65e1a0a3e304229a625c37f0e845c0c9fff117c8c1Theodore Ts'ostatic unsigned long version; 663839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 673627e83830995a8d3c00b391241909f7b6b44a76Li Xistatic int set_project; 683627e83830995a8d3c00b391241909f7b6b44a76Li Xistatic unsigned long project; 693627e83830995a8d3c00b391241909f7b6b44a76Li Xi 709a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'ostatic int recursive; 719a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'ostatic int verbose; 72e68594d2376afd10e03b440b4bc288508ad13aa2Theodore Ts'ostatic int silent; 733839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 74e1a0a3e304229a625c37f0e845c0c9fff117c8c1Theodore Ts'ostatic unsigned long af; 75e1a0a3e304229a625c37f0e845c0c9fff117c8c1Theodore Ts'ostatic unsigned long rf; 76e1a0a3e304229a625c37f0e845c0c9fff117c8c1Theodore Ts'ostatic unsigned long sf; 773839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 78b705640ae162093d40fc9f77e716bec891561ffeTheodore Ts'o#ifdef _LFS64_LARGEFILE 79b705640ae162093d40fc9f77e716bec891561ffeTheodore Ts'o#define LSTAT lstat64 80b705640ae162093d40fc9f77e716bec891561ffeTheodore Ts'o#define STRUCT_STAT struct stat64 81b705640ae162093d40fc9f77e716bec891561ffeTheodore Ts'o#else 82b705640ae162093d40fc9f77e716bec891561ffeTheodore Ts'o#define LSTAT lstat 83b705640ae162093d40fc9f77e716bec891561ffeTheodore Ts'o#define STRUCT_STAT struct stat 84b705640ae162093d40fc9f77e716bec891561ffeTheodore Ts'o#endif 85b705640ae162093d40fc9f77e716bec891561ffeTheodore Ts'o 86642935c082ca22e1186fc9926fe06e4207d5ab56Theodore Ts'ostatic void usage(void) 873839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{ 88e68594d2376afd10e03b440b4bc288508ad13aa2Theodore Ts'o fprintf(stderr, 893627e83830995a8d3c00b391241909f7b6b44a76Li Xi _("Usage: %s [-pRVf] [-+=aAcCdDeijPsStTu] [-v version] files...\n"), 90642935c082ca22e1186fc9926fe06e4207d5ab56Theodore Ts'o program_name); 91642935c082ca22e1186fc9926fe06e4207d5ab56Theodore Ts'o exit(1); 923839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o} 933839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 949a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'ostruct flags_char { 959a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o unsigned long flag; 969a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o char optchar; 979a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o}; 989a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o 999a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'ostatic const struct flags_char flags_array[] = { 1009a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o { EXT2_NOATIME_FL, 'A' }, 1019a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o { EXT2_SYNC_FL, 'S' }, 10288372d5c4b2ebd0405446b42de65bf2b0ebb2408Theodore Ts'o { EXT2_DIRSYNC_FL, 'D' }, 1039a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o { EXT2_APPEND_FL, 'a' }, 1049a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o { EXT2_COMPR_FL, 'c' }, 1059a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o { EXT2_NODUMP_FL, 'd' }, 1067c8da6e3768bc7cc7ffde72b4f87fd2ec3c7c7e7Aneesh Kumar K.V { EXT4_EXTENTS_FL, 'e'}, 1079a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o { EXT2_IMMUTABLE_FL, 'i' }, 1089a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o { EXT3_JOURNAL_DATA_FL, 'j' }, 109e1cec4464bdaf93ea609de43c5cdeb6a1f553483Li Xi { EXT4_PROJINHERIT_FL, 'P' }, 1109a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o { EXT2_SECRM_FL, 's' }, 1119a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o { EXT2_UNRM_FL, 'u' }, 112b3f5b4c22939daba86465d05842bce76053bc3cfTheodore Ts'o { EXT2_NOTAIL_FL, 't' }, 11315f9011add4013d32ea2f7ca7dbf860f95b8ec53Theodore Ts'o { EXT2_TOPDIR_FL, 'T' }, 1140796e660859724f304155e094b6cf5739a610ae4Theodore Ts'o { FS_NOCOW_FL, 'C' }, 1159a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o { 0, 0 } 1169a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o}; 1179a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o 1189a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'ostatic unsigned long get_flag(char c) 1199a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o{ 1209a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o const struct flags_char *fp; 121efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 1229a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o for (fp = flags_array; fp->flag != 0; fp++) { 1239a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o if (fp->optchar == c) 1249a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o return fp->flag; 1259a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o } 1269a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o return 0; 1279a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o} 1289a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o 1299a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o 1303839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ostatic int decode_arg (int * i, int argc, char ** argv) 1313839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{ 1323839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o char * p; 1333839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o char * tmp; 1349a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o unsigned long fl; 1353839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 1363839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o switch (argv[*i][0]) 1373839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o { 1383839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o case '-': 1399a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o for (p = &argv[*i][1]; *p; p++) { 1409a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o if (*p == 'R') { 1413839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o recursive = 1; 1429a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o continue; 1439a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o } 1449a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o if (*p == 'V') { 1453839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o verbose = 1; 1469a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o continue; 1479a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o } 148e68594d2376afd10e03b440b4bc288508ad13aa2Theodore Ts'o if (*p == 'f') { 149e68594d2376afd10e03b440b4bc288508ad13aa2Theodore Ts'o silent = 1; 150e68594d2376afd10e03b440b4bc288508ad13aa2Theodore Ts'o continue; 151e68594d2376afd10e03b440b4bc288508ad13aa2Theodore Ts'o } 1523627e83830995a8d3c00b391241909f7b6b44a76Li Xi if (*p == 'p') { 1533627e83830995a8d3c00b391241909f7b6b44a76Li Xi (*i)++; 1543627e83830995a8d3c00b391241909f7b6b44a76Li Xi if (*i >= argc) 1553627e83830995a8d3c00b391241909f7b6b44a76Li Xi usage (); 1563627e83830995a8d3c00b391241909f7b6b44a76Li Xi project = strtol (argv[*i], &tmp, 0); 1573627e83830995a8d3c00b391241909f7b6b44a76Li Xi if (*tmp) { 1583627e83830995a8d3c00b391241909f7b6b44a76Li Xi com_err (program_name, 0, 1593627e83830995a8d3c00b391241909f7b6b44a76Li Xi _("bad project - %s\n"), 1603627e83830995a8d3c00b391241909f7b6b44a76Li Xi argv[*i]); 1613627e83830995a8d3c00b391241909f7b6b44a76Li Xi usage (); 1623627e83830995a8d3c00b391241909f7b6b44a76Li Xi } 1633627e83830995a8d3c00b391241909f7b6b44a76Li Xi set_project = 1; 1643627e83830995a8d3c00b391241909f7b6b44a76Li Xi continue; 1653627e83830995a8d3c00b391241909f7b6b44a76Li Xi } 1669a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o if (*p == 'v') { 1671e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o (*i)++; 1683839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (*i >= argc) 1693839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o usage (); 1703839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o version = strtol (argv[*i], &tmp, 0); 1719a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o if (*tmp) { 1723839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o com_err (program_name, 0, 173e68594d2376afd10e03b440b4bc288508ad13aa2Theodore Ts'o _("bad version - %s\n"), 1749a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o argv[*i]); 1753839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o usage (); 1763839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 1773839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o set_version = 1; 1789a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o continue; 1793839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 1809a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o if ((fl = get_flag(*p)) == 0) 1819a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o usage(); 1829a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o rf |= fl; 1839a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o rem = 1; 1849a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o } 1853839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o break; 1863839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o case '+': 1873839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o add = 1; 1889a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o for (p = &argv[*i][1]; *p; p++) { 1899a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o if ((fl = get_flag(*p)) == 0) 1909a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o usage(); 1919a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o af |= fl; 1929a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o } 1933839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o break; 1943839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o case '=': 1953839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o set = 1; 1969a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o for (p = &argv[*i][1]; *p; p++) { 1979a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o if ((fl = get_flag(*p)) == 0) 1989a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o usage(); 1999a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o sf |= fl; 2009a7188496851014f62592077b2ec603cc2c300a6Theodore Ts'o } 2013839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o break; 2023839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o default: 2033839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o return EOF; 2043839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o break; 2053839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 2063839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o return 1; 2073839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o} 2083839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 2092d328bb76d2d63bdfdba923b54c28bd686bd8fecTheodore Ts'ostatic int chattr_dir_proc(const char *, struct dirent *, void *); 2103839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 2112d328bb76d2d63bdfdba923b54c28bd686bd8fecTheodore Ts'ostatic int change_attributes(const char * name) 2123839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{ 2133839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o unsigned long flags; 214b705640ae162093d40fc9f77e716bec891561ffeTheodore Ts'o STRUCT_STAT st; 2153839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 216b705640ae162093d40fc9f77e716bec891561ffeTheodore Ts'o if (LSTAT (name, &st) == -1) { 217e68594d2376afd10e03b440b4bc288508ad13aa2Theodore Ts'o if (!silent) 218e68594d2376afd10e03b440b4bc288508ad13aa2Theodore Ts'o com_err (program_name, errno, 219e68594d2376afd10e03b440b4bc288508ad13aa2Theodore Ts'o _("while trying to stat %s"), name); 220e68594d2376afd10e03b440b4bc288508ad13aa2Theodore Ts'o return -1; 2213839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 222e1a0a3e304229a625c37f0e845c0c9fff117c8c1Theodore Ts'o 2237c8da6e3768bc7cc7ffde72b4f87fd2ec3c7c7e7Aneesh Kumar K.V if (fgetflags(name, &flags) == -1) { 2247c8da6e3768bc7cc7ffde72b4f87fd2ec3c7c7e7Aneesh Kumar K.V if (!silent) 2257c8da6e3768bc7cc7ffde72b4f87fd2ec3c7c7e7Aneesh Kumar K.V com_err(program_name, errno, 2267c8da6e3768bc7cc7ffde72b4f87fd2ec3c7c7e7Aneesh Kumar K.V _("while reading flags on %s"), name); 2277c8da6e3768bc7cc7ffde72b4f87fd2ec3c7c7e7Aneesh Kumar K.V return -1; 2287c8da6e3768bc7cc7ffde72b4f87fd2ec3c7c7e7Aneesh Kumar K.V } 229e1a0a3e304229a625c37f0e845c0c9fff117c8c1Theodore Ts'o if (set) { 230e1a0a3e304229a625c37f0e845c0c9fff117c8c1Theodore Ts'o if (verbose) { 231d9c56d3ca0bee11e3446ff7e12e3124d28e298a7Theodore Ts'o printf (_("Flags of %s set as "), name); 232f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o print_flags (stdout, sf, 0); 2333839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o printf ("\n"); 2343839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 2353839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (fsetflags (name, sf) == -1) 2363839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o perror (name); 237e1a0a3e304229a625c37f0e845c0c9fff117c8c1Theodore Ts'o } else { 2387c8da6e3768bc7cc7ffde72b4f87fd2ec3c7c7e7Aneesh Kumar K.V if (rem) 2397c8da6e3768bc7cc7ffde72b4f87fd2ec3c7c7e7Aneesh Kumar K.V flags &= ~rf; 2407c8da6e3768bc7cc7ffde72b4f87fd2ec3c7c7e7Aneesh Kumar K.V if (add) 2417c8da6e3768bc7cc7ffde72b4f87fd2ec3c7c7e7Aneesh Kumar K.V flags |= af; 2427c8da6e3768bc7cc7ffde72b4f87fd2ec3c7c7e7Aneesh Kumar K.V if (verbose) { 2437c8da6e3768bc7cc7ffde72b4f87fd2ec3c7c7e7Aneesh Kumar K.V printf(_("Flags of %s set as "), name); 2447c8da6e3768bc7cc7ffde72b4f87fd2ec3c7c7e7Aneesh Kumar K.V print_flags(stdout, flags, 0); 2457c8da6e3768bc7cc7ffde72b4f87fd2ec3c7c7e7Aneesh Kumar K.V printf("\n"); 2467c8da6e3768bc7cc7ffde72b4f87fd2ec3c7c7e7Aneesh Kumar K.V } 2477c8da6e3768bc7cc7ffde72b4f87fd2ec3c7c7e7Aneesh Kumar K.V if (!S_ISDIR(st.st_mode)) 2487c8da6e3768bc7cc7ffde72b4f87fd2ec3c7c7e7Aneesh Kumar K.V flags &= ~EXT2_DIRSYNC_FL; 2497c8da6e3768bc7cc7ffde72b4f87fd2ec3c7c7e7Aneesh Kumar K.V if (fsetflags(name, flags) == -1) { 2507c8da6e3768bc7cc7ffde72b4f87fd2ec3c7c7e7Aneesh Kumar K.V if (!silent) { 2517c8da6e3768bc7cc7ffde72b4f87fd2ec3c7c7e7Aneesh Kumar K.V com_err(program_name, errno, 252e68594d2376afd10e03b440b4bc288508ad13aa2Theodore Ts'o _("while setting flags on %s"), 253e68594d2376afd10e03b440b4bc288508ad13aa2Theodore Ts'o name); 254e68594d2376afd10e03b440b4bc288508ad13aa2Theodore Ts'o } 2557c8da6e3768bc7cc7ffde72b4f87fd2ec3c7c7e7Aneesh Kumar K.V return -1; 2563839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 2573839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 258e1a0a3e304229a625c37f0e845c0c9fff117c8c1Theodore Ts'o if (set_version) { 2593839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (verbose) 260d9c56d3ca0bee11e3446ff7e12e3124d28e298a7Theodore Ts'o printf (_("Version of %s set as %lu\n"), name, version); 261e68594d2376afd10e03b440b4bc288508ad13aa2Theodore Ts'o if (fsetversion (name, version) == -1) { 262e68594d2376afd10e03b440b4bc288508ad13aa2Theodore Ts'o if (!silent) 263e68594d2376afd10e03b440b4bc288508ad13aa2Theodore Ts'o com_err (program_name, errno, 264e68594d2376afd10e03b440b4bc288508ad13aa2Theodore Ts'o _("while setting version on %s"), 265e68594d2376afd10e03b440b4bc288508ad13aa2Theodore Ts'o name); 266e68594d2376afd10e03b440b4bc288508ad13aa2Theodore Ts'o return -1; 267e68594d2376afd10e03b440b4bc288508ad13aa2Theodore Ts'o } 2683839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 2693627e83830995a8d3c00b391241909f7b6b44a76Li Xi if (set_project) { 2703627e83830995a8d3c00b391241909f7b6b44a76Li Xi if (verbose) 27125040c0431e4f8508f643bc731e4b4034fdd9b82Theodore Ts'o printf (_("Project of %s set as %lu\n"), name, project); 2723627e83830995a8d3c00b391241909f7b6b44a76Li Xi if (fsetproject (name, project) == -1) { 2733627e83830995a8d3c00b391241909f7b6b44a76Li Xi if (!silent) 2743627e83830995a8d3c00b391241909f7b6b44a76Li Xi com_err (program_name, errno, 2753627e83830995a8d3c00b391241909f7b6b44a76Li Xi _("while setting project on %s"), 2763627e83830995a8d3c00b391241909f7b6b44a76Li Xi name); 2773627e83830995a8d3c00b391241909f7b6b44a76Li Xi return -1; 2783627e83830995a8d3c00b391241909f7b6b44a76Li Xi } 2793627e83830995a8d3c00b391241909f7b6b44a76Li Xi 2803627e83830995a8d3c00b391241909f7b6b44a76Li Xi } 2813839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (S_ISDIR(st.st_mode) && recursive) 282e68594d2376afd10e03b440b4bc288508ad13aa2Theodore Ts'o return iterate_on_dir (name, chattr_dir_proc, NULL); 283e68594d2376afd10e03b440b4bc288508ad13aa2Theodore Ts'o return 0; 2843839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o} 2853839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 286e1a0a3e304229a625c37f0e845c0c9fff117c8c1Theodore Ts'ostatic int chattr_dir_proc (const char * dir_name, struct dirent * de, 287544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o void * private EXT2FS_ATTR((unused))) 2883839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{ 289e68594d2376afd10e03b440b4bc288508ad13aa2Theodore Ts'o int ret = 0; 290e68594d2376afd10e03b440b4bc288508ad13aa2Theodore Ts'o 291e1a0a3e304229a625c37f0e845c0c9fff117c8c1Theodore Ts'o if (strcmp (de->d_name, ".") && strcmp (de->d_name, "..")) { 292a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o char *path; 293a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o 294a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o path = malloc(strlen (dir_name) + 1 + strlen (de->d_name) + 1); 295642935c082ca22e1186fc9926fe06e4207d5ab56Theodore Ts'o if (!path) { 29645ff69ffeb700012a7c052f5e45882557a40be7eAndreas Dilger fprintf(stderr, "%s", 29745ff69ffeb700012a7c052f5e45882557a40be7eAndreas Dilger _("Couldn't allocate path variable " 29845ff69ffeb700012a7c052f5e45882557a40be7eAndreas Dilger "in chattr_dir_proc")); 299e68594d2376afd10e03b440b4bc288508ad13aa2Theodore Ts'o return -1; 300642935c082ca22e1186fc9926fe06e4207d5ab56Theodore Ts'o } 301e68594d2376afd10e03b440b4bc288508ad13aa2Theodore Ts'o sprintf(path, "%s/%s", dir_name, de->d_name); 3022d328bb76d2d63bdfdba923b54c28bd686bd8fecTheodore Ts'o ret = change_attributes(path); 303a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o free(path); 3043839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 305e68594d2376afd10e03b440b4bc288508ad13aa2Theodore Ts'o return ret; 3063839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o} 3073839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 30800e5433eb5e9f70f485968b809fdcf297d7fe7b9Theodore Ts'oint main (int argc, char ** argv) 3093839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{ 3103839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o int i, j; 3113839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o int end_arg = 0; 312e68594d2376afd10e03b440b4bc288508ad13aa2Theodore Ts'o int err, retval = 0; 3133839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 314d9c56d3ca0bee11e3446ff7e12e3124d28e298a7Theodore Ts'o#ifdef ENABLE_NLS 315d9c56d3ca0bee11e3446ff7e12e3124d28e298a7Theodore Ts'o setlocale(LC_MESSAGES, ""); 31614308a5398984842e808faa3ff2dd6a1c52d90bdTheodore Ts'o setlocale(LC_CTYPE, ""); 317d9c56d3ca0bee11e3446ff7e12e3124d28e298a7Theodore Ts'o bindtextdomain(NLS_CAT_NAME, LOCALEDIR); 318d9c56d3ca0bee11e3446ff7e12e3124d28e298a7Theodore Ts'o textdomain(NLS_CAT_NAME); 3199d4507c5b61007df968638623aa1b4c47dae6cf9Theodore Ts'o set_com_err_gettext(gettext); 320d9c56d3ca0bee11e3446ff7e12e3124d28e298a7Theodore Ts'o#endif 3213839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (argc && *argv) 3223839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o program_name = *argv; 3233839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o i = 1; 324e1a0a3e304229a625c37f0e845c0c9fff117c8c1Theodore Ts'o while (i < argc && !end_arg) { 3252293a4d5deb30b02d90c4d0aee516e8280092a58Theodore Ts'o /* '--' arg should end option processing */ 3262293a4d5deb30b02d90c4d0aee516e8280092a58Theodore Ts'o if (strcmp(argv[i], "--") == 0) { 3272293a4d5deb30b02d90c4d0aee516e8280092a58Theodore Ts'o i++; 3282293a4d5deb30b02d90c4d0aee516e8280092a58Theodore Ts'o end_arg = 1; 3292293a4d5deb30b02d90c4d0aee516e8280092a58Theodore Ts'o } else if (decode_arg (&i, argc, argv) == EOF) 3303839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o end_arg = 1; 3313839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o else 3323839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o i++; 3333839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 3343839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (i >= argc) 3353839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o usage (); 336e1a0a3e304229a625c37f0e845c0c9fff117c8c1Theodore Ts'o if (set && (add || rem)) { 337544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o fputs(_("= is incompatible with - and +\n"), stderr); 3383839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o exit (1); 3393839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 340e1a0a3e304229a625c37f0e845c0c9fff117c8c1Theodore Ts'o if ((rf & af) != 0) { 341544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o fputs("Can't both set and unset same flag.\n", stderr); 342e1a0a3e304229a625c37f0e845c0c9fff117c8c1Theodore Ts'o exit (1); 343e1a0a3e304229a625c37f0e845c0c9fff117c8c1Theodore Ts'o } 3443627e83830995a8d3c00b391241909f7b6b44a76Li Xi if (!(add || rem || set || set_version || set_project )) { 345544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o fputs(_("Must use '-v', =, - or +\n"), stderr); 3463839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o exit (1); 3473839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 348a88fa0c0135307288562d4922438ae52fdbad855Theodore Ts'o if (verbose) 3490f8973fb092a40fd0a11b7ec95c09128c9fb8f0cTheodore Ts'o fprintf (stderr, "chattr %s (%s)\n", 3500f8973fb092a40fd0a11b7ec95c09128c9fb8f0cTheodore Ts'o E2FSPROGS_VERSION, E2FSPROGS_DATE); 351e68594d2376afd10e03b440b4bc288508ad13aa2Theodore Ts'o for (j = i; j < argc; j++) { 3522d328bb76d2d63bdfdba923b54c28bd686bd8fecTheodore Ts'o err = change_attributes (argv[j]); 353e68594d2376afd10e03b440b4bc288508ad13aa2Theodore Ts'o if (err) 354e68594d2376afd10e03b440b4bc288508ad13aa2Theodore Ts'o retval = 1; 355e68594d2376afd10e03b440b4bc288508ad13aa2Theodore Ts'o } 356e68594d2376afd10e03b440b4bc288508ad13aa2Theodore Ts'o exit(retval); 3573839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o} 358