aboutsummaryrefslogtreecommitdiffstats
path: root/misc/chattr.c
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>1997-04-26 13:21:57 +0000
committerTheodore Ts'o <tytso@mit.edu>1997-04-26 13:21:57 +0000
commit3839e65723771b85975f4263102dd3ceec4523c0 (patch)
tree02fde6f8259837e842e12bdc97bb9f92e4155b44 /misc/chattr.c
downloadandroid_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.c261
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]);
+}