chattr.c revision 36caf25f8d61eb8ffddc9895463bce5807e96808
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 21a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o#include <sys/types.h> 223839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <dirent.h> 233839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <fcntl.h> 243839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <stdio.h> 253839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <stdlib.h> 263839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <unistd.h> 2719c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o#include <string.h> 28a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o#ifdef HAVE_ERRNO_H 29a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o#include <errno.h> 30a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o#endif 313839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <sys/param.h> 323839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <sys/stat.h> 333839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <linux/ext2_fs.h> 343839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 3536caf25f8d61eb8ffddc9895463bce5807e96808Theodore Ts'o#ifndef S_ISLNK /* So we can compile even with gcc-warn */ 3636caf25f8d61eb8ffddc9895463bce5807e96808Theodore Ts'o# ifdef __S_IFLNK 3736caf25f8d61eb8ffddc9895463bce5807e96808Theodore Ts'o# define S_ISLNK(mode) __S_ISTYPE((mode), __S_IFLNK) 3836caf25f8d61eb8ffddc9895463bce5807e96808Theodore Ts'o# else 3936caf25f8d61eb8ffddc9895463bce5807e96808Theodore Ts'o# define S_ISLNK(mode) 0 4036caf25f8d61eb8ffddc9895463bce5807e96808Theodore Ts'o# endif 4136caf25f8d61eb8ffddc9895463bce5807e96808Theodore Ts'o#endif 4236caf25f8d61eb8ffddc9895463bce5807e96808Theodore Ts'o 433839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include "et/com_err.h" 443839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include "e2p/e2p.h" 453839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 463839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include "../version.h" 473839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 483839e65723771b85975f4263102dd3ceec4523cTheodore Ts'oconst char * program_name = "chattr"; 493839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 503839e65723771b85975f4263102dd3ceec4523cTheodore Ts'oint add = 0; 513839e65723771b85975f4263102dd3ceec4523cTheodore Ts'oint rem = 0; 523839e65723771b85975f4263102dd3ceec4523cTheodore Ts'oint set = 0; 533839e65723771b85975f4263102dd3ceec4523cTheodore Ts'oint set_version = 0; 543839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 553839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ounsigned long version; 563839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 573839e65723771b85975f4263102dd3ceec4523cTheodore Ts'oint recursive = 0; 583839e65723771b85975f4263102dd3ceec4523cTheodore Ts'oint verbose = 0; 593839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 603839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ounsigned long af; 613839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ounsigned long rf; 623839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ounsigned long sf; 633839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 64818180cdfcff84b9048ecdc5dc86323f0fefba24Theodore Ts'ostatic void fatal_error(const char * fmt_string, int errcode) 653839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{ 663839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o fprintf (stderr, fmt_string, program_name); 673839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o exit (errcode); 683839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o} 693839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 70818180cdfcff84b9048ecdc5dc86323f0fefba24Theodore Ts'o#define usage() fatal_error("usage: %s [-RV] [-+=AacdisSu] [-v version] files...\n", \ 713839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 1) 723839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 733839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ostatic int decode_arg (int * i, int argc, char ** argv) 743839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{ 753839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o char * p; 763839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o char * tmp; 773839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 783839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o switch (argv[*i][0]) 793839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o { 803839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o case '-': 813839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o for (p = &argv[*i][1]; *p; p++) 823839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o switch (*p) 833839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o { 843839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o case 'R': 853839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o recursive = 1; 863839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o break; 873839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o case 'S': 883839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o rf |= EXT2_SYNC_FL; 893839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o rem = 1; 903839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o break; 913839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o case 'V': 923839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o verbose = 1; 933839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o break; 94f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o#ifdef EXT2_APPEND_FL 95f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o case 'a': 96f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o rf |= EXT2_APPEND_FL; 97f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o rem = 1; 98f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o break; 99f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o#endif 1005c576477ccb2f0ca8c5d5af2e2354fd8eeff1589Theodore Ts'o#ifdef EXT2_NOATIME_FL 1015c576477ccb2f0ca8c5d5af2e2354fd8eeff1589Theodore Ts'o case 'A': 1025c576477ccb2f0ca8c5d5af2e2354fd8eeff1589Theodore Ts'o rf |= EXT2_NOATIME_FL; 1035c576477ccb2f0ca8c5d5af2e2354fd8eeff1589Theodore Ts'o rem = 1; 1045c576477ccb2f0ca8c5d5af2e2354fd8eeff1589Theodore Ts'o break; 1055c576477ccb2f0ca8c5d5af2e2354fd8eeff1589Theodore Ts'o#endif 1063839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o case 'c': 1073839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o rf |= EXT2_COMPR_FL; 1083839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o rem = 1; 1093839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o break; 110f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o#ifdef EXT2_NODUMP_FL 111f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o case 'd': 112f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o rf |= EXT2_NODUMP_FL; 113f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o rem = 1; 114f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o break; 115f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o#endif 116f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o#ifdef EXT2_IMMUTABLE_FL 117f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o case 'i': 118f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o rf |= EXT2_IMMUTABLE_FL; 119f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o rem = 1; 120f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o break; 121f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o#endif 1223839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o case 's': 1233839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o rf |= EXT2_SECRM_FL; 1243839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o rem = 1; 1253839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o break; 1263839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o case 'u': 1273839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o rf |= EXT2_UNRM_FL; 1283839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o rem = 1; 1293839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o break; 1303839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o case 'v': 1311e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o (*i)++; 1323839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (*i >= argc) 1333839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o usage (); 1343839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o version = strtol (argv[*i], &tmp, 0); 1353839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (*tmp) 1363839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o { 1373839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o com_err (program_name, 0, 1383839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o "bad version - %s\n", argv[*i]); 1393839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o usage (); 1403839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 1413839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o set_version = 1; 1423839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o break; 1433839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o default: 1443839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o fprintf (stderr, "%s: Unrecognized argument: %c\n", 1453839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o program_name, *p); 1463839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o usage (); 1473839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 1483839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o break; 1493839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o case '+': 1503839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o add = 1; 1513839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o for (p = &argv[*i][1]; *p; p++) 1523839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o switch (*p) 1533839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o { 1543839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o case 'S': 1553839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o af |= EXT2_SYNC_FL; 1563839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o break; 157f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o#ifdef EXT2_APPEND_FL 158f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o case 'a': 159f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o af |= EXT2_APPEND_FL; 160f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o break; 161f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o#endif 1625c576477ccb2f0ca8c5d5af2e2354fd8eeff1589Theodore Ts'o#ifdef EXT2_NOATIME_FL 1635c576477ccb2f0ca8c5d5af2e2354fd8eeff1589Theodore Ts'o case 'A': 1645c576477ccb2f0ca8c5d5af2e2354fd8eeff1589Theodore Ts'o af |= EXT2_NOATIME_FL; 1655c576477ccb2f0ca8c5d5af2e2354fd8eeff1589Theodore Ts'o break; 1665c576477ccb2f0ca8c5d5af2e2354fd8eeff1589Theodore Ts'o#endif 1673839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o case 'c': 1683839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o af |= EXT2_COMPR_FL; 1693839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o break; 170f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o#ifdef EXT2_NODUMP_FL 171f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o case 'd': 172f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o af |= EXT2_NODUMP_FL; 173f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o break; 174f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o#endif 175f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o#ifdef EXT2_IMMUTABLE_FL 176f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o case 'i': 177f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o af |= EXT2_IMMUTABLE_FL; 178f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o break; 179f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o#endif 1803839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o case 's': 1813839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o af |= EXT2_SECRM_FL; 1823839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o break; 1833839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o case 'u': 1843839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o af |= EXT2_UNRM_FL; 1853839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o break; 1863839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o default: 1873839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o usage (); 1883839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 1893839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o break; 1903839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o case '=': 1913839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o set = 1; 1923839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o for (p = &argv[*i][1]; *p; p++) 1933839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o switch (*p) 1943839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o { 1953839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o case 'S': 1963839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o sf |= EXT2_SYNC_FL; 1973839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o break; 198f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o#ifdef EXT2_APPEND_FL 199f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o case 'a': 200f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o sf |= EXT2_APPEND_FL; 201f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o break; 202f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o#endif 2035c576477ccb2f0ca8c5d5af2e2354fd8eeff1589Theodore Ts'o#ifdef EXT2_NOATIME_FL 2045c576477ccb2f0ca8c5d5af2e2354fd8eeff1589Theodore Ts'o case 'A': 2055c576477ccb2f0ca8c5d5af2e2354fd8eeff1589Theodore Ts'o sf |= EXT2_NOATIME_FL; 2065c576477ccb2f0ca8c5d5af2e2354fd8eeff1589Theodore Ts'o break; 2075c576477ccb2f0ca8c5d5af2e2354fd8eeff1589Theodore Ts'o#endif 2083839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o case 'c': 2093839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o sf |= EXT2_COMPR_FL; 2103839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o break; 211f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o#ifdef EXT2_NODUMP_FL 212f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o case 'd': 213f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o sf |= EXT2_NODUMP_FL; 214f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o break; 215f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o#endif 216f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o#ifdef EXT2_IMMUTABLE_FL 217f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o case 'i': 218f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o sf |= EXT2_IMMUTABLE_FL; 219f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o break; 220f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o#endif 2213839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o case 's': 2223839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o sf |= EXT2_SECRM_FL; 2233839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o break; 2243839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o case 'u': 2253839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o sf |= EXT2_UNRM_FL; 2263839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o break; 2273839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o default: 2283839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o usage (); 2293839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 2303839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o break; 2313839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o default: 2323839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o return EOF; 2333839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o break; 2343839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 2353839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o return 1; 2363839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o} 2373839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 2383839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ostatic int chattr_dir_proc (const char *, struct dirent *, void *); 2393839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 2403839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ostatic void change_attributes (const char * name) 2413839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{ 2423839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o unsigned long flags; 2433839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o struct stat st; 2443839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 2453839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (lstat (name, &st) == -1) 2463839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o { 2473839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o com_err (program_name, errno, "while stating %s", name); 2483839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o return; 2493839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 250a88fa0c0135307288562d4922438ae52fdbad855Theodore Ts'o if (S_ISLNK(st.st_mode) && recursive) 251a88fa0c0135307288562d4922438ae52fdbad855Theodore Ts'o return; 2523839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (set) 2533839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o { 2543839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (verbose) 2553839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o { 2563839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o printf ("Flags of %s set as ", name); 257f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o print_flags (stdout, sf, 0); 2583839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o printf ("\n"); 2593839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 2603839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (fsetflags (name, sf) == -1) 2613839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o perror (name); 2623839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 2633839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o else 2643839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o { 2653839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (fgetflags (name, &flags) == -1) 2663839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o com_err (program_name, errno, 2673839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o "while reading flags on %s", name); 2683839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o else 2693839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o { 2703839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (rem) 2713839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o flags &= ~rf; 2723839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (add) 2733839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o flags |= af; 2743839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (verbose) 2753839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o { 2763839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o printf ("Flags of %s set as ", name); 277f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o print_flags (stdout, flags, 0); 2783839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o printf ("\n"); 2793839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 2803839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (fsetflags (name, flags) == -1) 2813839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o com_err (program_name, errno, 2823839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o "while setting flags on %s", name); 2833839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 2843839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 2853839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (set_version) 2863839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o { 2873839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (verbose) 2883839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o printf ("Version of %s set as %lu\n", name, version); 2893839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (fsetversion (name, version) == -1) 2903839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o com_err (program_name, errno, 2913839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o "while setting version on %s", name); 2923839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 2933839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (S_ISDIR(st.st_mode) && recursive) 2943839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o iterate_on_dir (name, chattr_dir_proc, (void *) NULL); 2953839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o} 2963839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 2973839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ostatic int chattr_dir_proc (const char * dir_name, struct dirent * de, void * private) 2983839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{ 2993839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (strcmp (de->d_name, ".") && strcmp (de->d_name, "..")) 3003839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o { 301a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o char *path; 302a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o 303a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o path = malloc(strlen (dir_name) + 1 + strlen (de->d_name) + 1); 304a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o if (!path) 305a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o fatal_error("Couldn't allocate path variable " 306a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o "in chattr_dir_proc", 1); 3073839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o sprintf (path, "%s/%s", dir_name, de->d_name); 3083839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o change_attributes (path); 309a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o free(path); 3103839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 3113839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o return 0; 3123839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o} 3133839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 31400e5433eb5e9f70f485968b809fdcf297d7fe7b9Theodore Ts'oint main (int argc, char ** argv) 3153839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{ 3163839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o int i, j; 3173839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o int end_arg = 0; 3183839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 3193839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (argc && *argv) 3203839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o program_name = *argv; 3213839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o i = 1; 3223839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o while (i < argc && !end_arg) 3233839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o { 3243839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (decode_arg (&i, argc, argv) == EOF) 3253839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o end_arg = 1; 3263839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o else 3273839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o i++; 3283839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 3293839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (i >= argc) 3303839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o usage (); 3313839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (set && (add || rem)) 3323839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o { 3333839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o fprintf (stderr, "= is incompatible with - and +\n"); 3343839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o exit (1); 3353839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 3361e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o if (!(add || rem || set || set_version)) 3373839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o { 3381e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o fprintf (stderr, "Must use '-v', =, - or +\n"); 3393839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o exit (1); 3403839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 341a88fa0c0135307288562d4922438ae52fdbad855Theodore Ts'o if (verbose) 342a88fa0c0135307288562d4922438ae52fdbad855Theodore Ts'o fprintf (stderr, "chattr %s, %s for EXT2 FS %s, %s\n", 343a88fa0c0135307288562d4922438ae52fdbad855Theodore Ts'o E2FSPROGS_VERSION, E2FSPROGS_DATE, 344a88fa0c0135307288562d4922438ae52fdbad855Theodore Ts'o EXT2FS_VERSION, EXT2FS_DATE); 3453839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o for (j = i; j < argc; j++) 3463839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o change_attributes (argv[j]); 34700e5433eb5e9f70f485968b809fdcf297d7fe7b9Theodore Ts'o exit(0); 3483839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o} 349