diff options
author | Theodore Ts'o <tytso@mit.edu> | 1997-04-26 13:21:57 +0000 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 1997-04-26 13:21:57 +0000 |
commit | 3839e65723771b85975f4263102dd3ceec4523c0 (patch) | |
tree | 02fde6f8259837e842e12bdc97bb9f92e4155b44 /misc/chattr.c | |
download | android_external_e2fsprogs-3839e65723771b85975f4263102dd3ceec4523c0.tar.gz android_external_e2fsprogs-3839e65723771b85975f4263102dd3ceec4523c0.tar.bz2 android_external_e2fsprogs-3839e65723771b85975f4263102dd3ceec4523c0.zip |
Many files:
Checkin of e2fsprogs 0.5b
Diffstat (limited to 'misc/chattr.c')
-rw-r--r-- | misc/chattr.c | 261 |
1 files changed, 261 insertions, 0 deletions
diff --git a/misc/chattr.c b/misc/chattr.c new file mode 100644 index 00000000..63c8108c --- /dev/null +++ b/misc/chattr.c @@ -0,0 +1,261 @@ +/* + * chattr.c - Change file attributes on an ext2 file system + * + * Copyright (C) 1993, 1994 Remy Card <card@masi.ibp.fr> + * Laboratoire MASI, Institut Blaise Pascal + * Universite Pierre et Marie Curie (Paris VI) + * + * This file can be redistributed under the terms of the GNU General + * Public License + */ + +/* + * History: + * 93/10/30 - Creation + * 93/11/13 - Replace stat() calls by lstat() to avoid loops + * 94/02/27 - Integrated in Ted's distribution + */ + +#include <dirent.h> +#include <fcntl.h> +#include <getopt.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/param.h> +#include <sys/stat.h> +#include <linux/ext2_fs.h> + +#include "et/com_err.h" +#include "e2p/e2p.h" + +#include "../version.h" + +const char * program_name = "chattr"; + +int add = 0; +int rem = 0; +int set = 0; +int set_version = 0; + +unsigned long version; + +int recursive = 0; +int verbose = 0; + +unsigned long af; +unsigned long rf; +unsigned long sf; + +static void volatile fatal_error (const char * fmt_string, int errcode) +{ + fprintf (stderr, fmt_string, program_name); + exit (errcode); +} + +#define usage() fatal_error ("usage: %s [-RV] [-+=csu] [-v version] files...\n", \ + 1) + +static int decode_arg (int * i, int argc, char ** argv) +{ + char * p; + char * tmp; + + switch (argv[*i][0]) + { + case '-': + for (p = &argv[*i][1]; *p; p++) + switch (*p) + { + case 'R': + recursive = 1; + break; + case 'S': + rf |= EXT2_SYNC_FL; + rem = 1; + break; + case 'V': + verbose = 1; + break; + case 'c': + rf |= EXT2_COMPR_FL; + rem = 1; + break; + case 's': + rf |= EXT2_SECRM_FL; + rem = 1; + break; + case 'u': + rf |= EXT2_UNRM_FL; + rem = 1; + break; + case 'v': + if (*i >= argc) + usage (); + (*i)++; + version = strtol (argv[*i], &tmp, 0); + if (*tmp) + { + com_err (program_name, 0, + "bad version - %s\n", argv[*i]); + usage (); + } + set_version = 1; + break; + default: + fprintf (stderr, "%s: Unrecognized argument: %c\n", + program_name, *p); + usage (); + } + break; + case '+': + add = 1; + for (p = &argv[*i][1]; *p; p++) + switch (*p) + { + case 'S': + af |= EXT2_SYNC_FL; + break; + case 'c': + af |= EXT2_COMPR_FL; + break; + case 's': + af |= EXT2_SECRM_FL; + break; + case 'u': + af |= EXT2_UNRM_FL; + break; + default: + usage (); + } + break; + case '=': + set = 1; + for (p = &argv[*i][1]; *p; p++) + switch (*p) + { + case 'S': + sf |= EXT2_SYNC_FL; + break; + case 'c': + sf |= EXT2_COMPR_FL; + break; + case 's': + sf |= EXT2_SECRM_FL; + break; + case 'u': + sf |= EXT2_UNRM_FL; + break; + default: + usage (); + } + break; + default: + return EOF; + break; + } + return 1; +} + +static int chattr_dir_proc (const char *, struct dirent *, void *); + +static void change_attributes (const char * name) +{ + unsigned long flags; + struct stat st; + + if (lstat (name, &st) == -1) + { + com_err (program_name, errno, "while stating %s", name); + return; + } + if (set) + { + if (verbose) + { + printf ("Flags of %s set as ", name); + print_flags (stdout, sf); + printf ("\n"); + } + if (fsetflags (name, sf) == -1) + perror (name); + } + else + { + if (fgetflags (name, &flags) == -1) + com_err (program_name, errno, + "while reading flags on %s", name); + else + { + if (rem) + flags &= ~rf; + if (add) + flags |= af; + if (verbose) + { + printf ("Flags of %s set as ", name); + print_flags (stdout, flags); + printf ("\n"); + } + if (fsetflags (name, flags) == -1) + com_err (program_name, errno, + "while setting flags on %s", name); + } + } + if (set_version) + { + if (verbose) + printf ("Version of %s set as %lu\n", name, version); + if (fsetversion (name, version) == -1) + com_err (program_name, errno, + "while setting version on %s", name); + } + if (S_ISDIR(st.st_mode) && recursive) + iterate_on_dir (name, chattr_dir_proc, (void *) NULL); +} + +static int chattr_dir_proc (const char * dir_name, struct dirent * de, void * private) +{ + char path[MAXPATHLEN]; + + if (strcmp (de->d_name, ".") && strcmp (de->d_name, "..")) + { + sprintf (path, "%s/%s", dir_name, de->d_name); + change_attributes (path); + } + return 0; +} + +void main (int argc, char ** argv) +{ + int i, j; + int end_arg = 0; + + fprintf (stderr, "chattr %s, %s for EXT2 FS %s, %s\n", + E2FSPROGS_VERSION, E2FSPROGS_DATE, + EXT2FS_VERSION, EXT2FS_DATE); + if (argc && *argv) + program_name = *argv; + i = 1; + while (i < argc && !end_arg) + { + if (decode_arg (&i, argc, argv) == EOF) + end_arg = 1; + else + i++; + } + if (i >= argc) + usage (); + if (set && (add || rem)) + { + fprintf (stderr, "= is incompatible with - and +\n"); + exit (1); + } + if (!(add || rem || set)) + { + fprintf (stderr, "Must use =, - or +\n"); + exit (1); + } + for (j = i; j < argc; j++) + change_attributes (argv[j]); +} |