; ; ExtFS Context Information Patch ; Per Context Quota Support ; ; (C) 2003 Herbert Pötzl ; ; Changelog: ; ; 0.01 - first public release ; ; this patch is free software; you can redistribute it and/or ; modify it under the terms of the GNU General Public License ; as published by the Free Software Foundation; either version 2 ; of the License, or (at your option) any later version. ; ; this patch is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; GNU General Public License for more details. ; diff -NurpP --minimal e2fsprogs-1.34/misc/Makefile.in e2fsprogs-1.34-cti0.01/misc/Makefile.in --- e2fsprogs-1.34/misc/Makefile.in 2003-05-04 00:46:47.000000000 +0200 +++ e2fsprogs-1.34-cti0.01/misc/Makefile.in 2004-03-20 22:34:16.000000000 +0100 @@ -21,7 +21,7 @@ SMANPAGES= tune2fs.8 mklost+found.8 mke2 e2label.8 findfs.8 blkid.8 $(E2IMAGE_MAN) \ logsave.8 @FSCK_MAN@ -UPROGS= chattr lsattr uuidgen +UPROGS= chattr lsattr uuidgen lsctx chctx UMANPAGES= chattr.1 lsattr.1 uuidgen.1 TUNE2FS_OBJS= tune2fs.o util.o @@ -29,6 +29,8 @@ MKLPF_OBJS= mklost+found.o MKE2FS_OBJS= mke2fs.o util.o CHATTR_OBJS= chattr.o LSATTR_OBJS= lsattr.o +CHCTX_OBJS= chctx.o context.o +LSCTX_OBJS= lsctx.o context.o UUIDGEN_OBJS= uuidgen.o DUMPE2FS_OBJS= dumpe2fs.o BADBLOCKS_OBJS= badblocks.o @@ -99,6 +101,12 @@ chattr: $(CHATTR_OBJS) $(DEPLIBS_E2P) lsattr: $(LSATTR_OBJS) $(DEPLIBS_E2P) $(CC) $(ALL_LDFLAGS) -o lsattr $(LSATTR_OBJS) $(LIBS_E2P) $(LIBINTL) +chctx: $(CHCTX_OBJS) $(DEPLIBS_E2P) + $(CC) $(ALL_LDFLAGS) -o chctx $(CHCTX_OBJS) $(LIBS_E2P) $(LIBINTL) + +lsctx: $(LSCTX_OBJS) $(DEPLIBS_E2P) + $(CC) $(ALL_LDFLAGS) -o lsctx $(LSCTX_OBJS) $(LIBS_E2P) $(LIBINTL) + uuidgen: $(UUIDGEN_OBJS) $(DEPLIBUUID) $(CC) $(ALL_LDFLAGS) -o uuidgen $(UUIDGEN_OBJS) $(LIBUUID) $(LIBINTL) @@ -261,6 +269,14 @@ chattr.o: $(srcdir)/chattr.c $(top_srcdi lsattr.o: $(srcdir)/lsattr.c $(top_srcdir)/lib/ext2fs/ext2_fs.h \ $(top_builddir)/lib/ext2fs/ext2_types.h $(top_srcdir)/lib/et/com_err.h \ $(top_srcdir)/lib/e2p/e2p.h $(top_srcdir)/version.h $(srcdir)/nls-enable.h +chctx.o: $(srcdir)/chctx.c $(top_srcdir)/lib/ext2fs/ext2_fs.h \ + $(top_builddir)/lib/ext2fs/ext2_types.h $(top_srcdir)/lib/et/com_err.h \ + $(top_srcdir)/lib/e2p/e2p.h $(top_srcdir)/version.h $(srcdir)/nls-enable.h +lsctx.o: $(srcdir)/lsctx.c $(top_srcdir)/lib/ext2fs/ext2_fs.h \ + $(top_builddir)/lib/ext2fs/ext2_types.h $(top_srcdir)/lib/et/com_err.h \ + $(top_srcdir)/lib/e2p/e2p.h $(top_srcdir)/version.h $(srcdir)/nls-enable.h +context.o: $(srcdir)/context.c $(top_srcdir)/lib/e2p/e2p.h \ + $(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_builddir)/lib/ext2fs/ext2_types.h dumpe2fs.o: $(srcdir)/dumpe2fs.c $(top_srcdir)/lib/ext2fs/ext2_fs.h \ $(top_builddir)/lib/ext2fs/ext2_types.h $(top_srcdir)/lib/ext2fs/ext2fs.h \ $(top_srcdir)/lib/et/com_err.h $(top_srcdir)/lib/ext2fs/ext2_io.h \ diff -NurpP --minimal e2fsprogs-1.34/misc/chctx.c e2fsprogs-1.34-cti0.01/misc/chctx.c --- e2fsprogs-1.34/misc/chctx.c 1970-01-01 01:00:00.000000000 +0100 +++ e2fsprogs-1.34-cti0.01/misc/chctx.c 2004-03-20 22:34:16.000000000 +0100 @@ -0,0 +1,205 @@ +/* + * chctx.c - Change file context on an ext2 file system + * + * Copyright (C) 2003 Herbert Pötzl + * + * This file can be redistributed under the terms of the GNU General + * Public License + */ + +/* + * History: + * 2003/07/14 - Adaptation from chattr + */ + +#define _LARGEFILE64_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_ERRNO_H +#include +#endif +#include +#include +#include "ext2fs/ext2_fs.h" + +#ifndef S_ISLNK /* So we can compile even with gcc-warn */ +# ifdef __S_IFLNK +# define S_ISLNK(mode) __S_ISTYPE((mode), __S_IFLNK) +# else +# define S_ISLNK(mode) 0 +# endif +#endif + +#include "et/com_err.h" +#include "e2p/e2p.h" + +#include "../version.h" +#include "nls-enable.h" + +static const char * program_name = "chctx"; + +static int set; +static int set_version; + +static unsigned long version; + +static int recursive; +static int verbose; + +static unsigned long ctx; + +#ifdef _LFS64_LARGEFILE +#define LSTAT lstat64 +#define STRUCT_STAT struct stat64 +#else +#define LSTAT lstat +#define STRUCT_STAT struct stat +#endif + +static void fatal_error(const char * fmt_string, int errcode) +{ + fprintf (stderr, fmt_string, program_name); + exit (errcode); +} + +#define usage() fatal_error(_("usage: %s [-RV] ctx [-v version] files...\n"), \ + 1) + + +int fsetctx (const char *, unsigned long); + +static int decode_arg (int * i, int argc, char ** argv) +{ + char * p; + char * tmp; + unsigned long fl; + + switch (argv[*i][0]) + { + case '-': + for (p = &argv[*i][1]; *p; p++) { + if (*p == 'R') { + recursive = 1; + continue; + } + if (*p == 'V') { + verbose = 1; + continue; + } + if (*p == 'v') { + (*i)++; + if (*i >= argc) + usage (); + version = strtol (argv[*i], &tmp, 0); + if (*tmp) { + com_err (program_name, 0, + _("bad version - %s\n"), + argv[*i]); + usage (); + } + set_version = 1; + continue; + } + } + break; + default: + return EOF; + break; + } + return 1; +} + +static int chctx_dir_proc (const char *, struct dirent *, void *); + +static void change_context (const char * name) +{ + STRUCT_STAT st; + + if (LSTAT (name, &st) == -1) { + com_err (program_name, errno, _("while trying to stat %s"), + name); + return; + } + if (S_ISLNK(st.st_mode) && recursive) + return; + + /* Don't try to open device files, fifos etc. We probably + ought to display an error if the file was explicitly given + on the command line (whether or not recursive was + requested). */ + if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode) && + !S_ISDIR(st.st_mode)) + return; + + if (verbose) { + printf (_("Context of %s set as "), name); + print_ctx (stdout, ctx, 0); + printf ("\n"); + } + if (fsetctx (name, ctx) == -1) + perror (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, chctx_dir_proc, NULL); +} + +static int chctx_dir_proc (const char * dir_name, struct dirent * de, + void * unused_private) +{ + if (strcmp (de->d_name, ".") && strcmp (de->d_name, "..")) { + char *path; + + path = malloc(strlen (dir_name) + 1 + strlen (de->d_name) + 1); + if (!path) + fatal_error(_("Couldn't allocate path variable " + "in chctx_dir_proc"), 1); + sprintf (path, "%s/%s", dir_name, de->d_name); + change_context (path); + free(path); + } + return 0; +} + +int main (int argc, char ** argv) +{ + int i, j; + int end_arg = 0; + +#ifdef ENABLE_NLS + setlocale(LC_MESSAGES, ""); + setlocale(LC_CTYPE, ""); + bindtextdomain(NLS_CAT_NAME, LOCALEDIR); + textdomain(NLS_CAT_NAME); +#endif + 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-1) + usage (); + if (verbose) + fprintf (stderr, "chctx %s (%s)\n", + E2FSPROGS_VERSION, E2FSPROGS_DATE); + + ctx = atol( argv[i]); + for (j = i+1; j < argc; j++) + change_context (argv[j]); + exit(0); +} diff -NurpP --minimal e2fsprogs-1.34/misc/context.c e2fsprogs-1.34-cti0.01/misc/context.c --- e2fsprogs-1.34/misc/context.c 1970-01-01 01:00:00.000000000 +0100 +++ e2fsprogs-1.34-cti0.01/misc/context.c 2004-03-20 22:34:16.000000000 +0100 @@ -0,0 +1,98 @@ +/* + * context.c - helper for context info on ext2 fs + * + * Copyright (C) 2003 Herbert Pötzl + * + * This file can be redistributed under the terms of the GNU General + * Public License + */ + +/* + * History: + * 2003/07/14 - Adaptation from fgetflags + */ + +#define _LARGEFILE_SOURCE +#define _LARGEFILE64_SOURCE + +#if HAVE_ERRNO_H +#include +#endif +#if HAVE_UNISTD_H +#include +#endif +#include +#include +#if HAVE_EXT2_IOCTLS +#include +#include +#endif +#include +#include +#include + + +#ifdef O_LARGEFILE +#define OPEN_FLAGS (O_RDONLY|O_NONBLOCK|O_LARGEFILE) +#else +#define OPEN_FLAGS (O_RDONLY|O_NONBLOCK) +#endif + +#define EXT2_IOC_GETCONTEXT _IOR('x', 1, long) +#define EXT2_IOC_SETCONTEXT _IOW('x', 2, long) + + +void print_ctx (FILE * f, unsigned long ctx, unsigned options) +{ + fprintf(f, "#%ld", ctx); +} + +int fgetctx (const char * name, unsigned long * ctx) +{ + struct stat buf; +// #if HAVE_EXT2_IOCTLS + int fd, r, c, save_errno = 0; + + if (stat(name, &buf) != 0) + goto notsupp; + fd = open (name, OPEN_FLAGS); + if (fd == -1) + return -1; + r = ioctl (fd, EXT2_IOC_GETCONTEXT, &c); + if (r == -1) + save_errno = errno; + *ctx = c; + close (fd); + if (save_errno) + errno = save_errno; + return r; +// #endif /* HAVE_EXT2_IOCTLS */ +notsupp: + errno = EOPNOTSUPP; + return -1; +} + +int fsetctx (const char * name, unsigned long ctx) +{ + struct stat buf; +// #if HAVE_EXT2_IOCTLS + int fd, r, c, save_errno = 0; + + if (stat(name, &buf) != 0) + goto notsupp; + fd = open (name, OPEN_FLAGS); + if (fd == -1) + return -1; + c = (int) ctx; + r = ioctl (fd, EXT2_IOC_SETCONTEXT, &c); + if (r == -1) + save_errno = errno; + close (fd); + if (save_errno) + errno = save_errno; + return r; +// #endif /* HAVE_EXT2_IOCTLS */ +notsupp: + errno = EOPNOTSUPP; + return -1; +} diff -NurpP --minimal e2fsprogs-1.34/misc/lsctx.c e2fsprogs-1.34-cti0.01/misc/lsctx.c --- e2fsprogs-1.34/misc/lsctx.c 1970-01-01 01:00:00.000000000 +0100 +++ e2fsprogs-1.34-cti0.01/misc/lsctx.c 2004-03-20 22:34:16.000000000 +0100 @@ -0,0 +1,179 @@ +/* + * lsctx.c - List file context on an ext2 file system + * + * Copyright (C) 2003 Herbert Pötzl + * + * This file can be redistributed under the terms of the GNU General + * Public License + */ + +/* + * History: + * 2003/07/14 - Adaptation from lsattr + */ + +#define _LARGEFILE64_SOURCE + +#include +#include +#ifdef HAVE_ERRNO_H +#include +#endif +#include +#ifdef HAVE_GETOPT_H +#include +#else +extern int optind; +extern char *optarg; +#endif +#include +#include +#include +#include +#include +#include + +#include "ext2fs/ext2_fs.h" +#include "et/com_err.h" +#include "e2p/e2p.h" + +#include "../version.h" +#include "nls-enable.h" + +static const char * program_name = "lsctx"; + +static int all; +static int dirs_opt; +static int recursive; +static int verbose; +static int generation_opt; + +#ifdef _LFS64_LARGEFILE +#define LSTAT lstat64 +#define STRUCT_STAT struct stat64 +#else +#define LSTAT lstat +#define STRUCT_STAT struct stat +#endif + +static void usage(void) +{ + fprintf(stderr, _("Usage: %s [-RVadv] [files...]\n"), program_name); + exit(1); +} + +void print_ctx (FILE *, unsigned long, unsigned); +int fgetctx (const char *, unsigned long *); + + +static void list_context (const char * name) +{ + unsigned long ctx; + unsigned long generation; + + if (fgetctx (name, &ctx) == -1) { + com_err (program_name, errno, _("while reading context on %s"), + name); + return; + } + if (generation_opt) { + if (fgetversion (name, &generation) == -1) { + com_err (program_name, errno, + _("While reading version on %s"), + name); + return; + } + printf ("%5lu ", generation); + } + print_ctx(stdout, ctx, 0); + printf(" %s\n", name); +} + +static int lsctx_dir_proc (const char *, struct dirent *, void *); + +static void lsctx_args (const char * name) +{ + STRUCT_STAT st; + + if (LSTAT (name, &st) == -1) + com_err (program_name, errno, _("while trying to stat %s"), + name); + else { + if (S_ISDIR(st.st_mode) && !dirs_opt) + iterate_on_dir (name, lsctx_dir_proc, NULL); + else + list_context (name); + } +} + +static int lsctx_dir_proc (const char * dir_name, struct dirent * de, void * private) +{ + STRUCT_STAT st; + char *path; + + path = malloc(strlen (dir_name) + 1 + strlen (de->d_name) + 1); + + sprintf (path, "%s/%s", dir_name, de->d_name); + if (LSTAT (path, &st) == -1) + perror (path); + else { + if (de->d_name[0] != '.' || all) { + list_context (path); + if (S_ISDIR(st.st_mode) && recursive && + strcmp(de->d_name, ".") && + strcmp(de->d_name, "..")) { + printf ("\n%s:\n", path); + iterate_on_dir (path, lsctx_dir_proc, NULL); + printf ("\n"); + } + } + } + free(path); + return 0; +} + +int main (int argc, char ** argv) +{ + int c; + int i; + +#ifdef ENABLE_NLS + setlocale(LC_MESSAGES, ""); + setlocale(LC_CTYPE, ""); + bindtextdomain(NLS_CAT_NAME, LOCALEDIR); + textdomain(NLS_CAT_NAME); +#endif + if (argc && *argv) + program_name = *argv; + while ((c = getopt (argc, argv, "RVadv")) != EOF) + switch (c) + { + case 'R': + recursive = 1; + break; + case 'V': + verbose = 1; + break; + case 'a': + all = 1; + break; + case 'd': + dirs_opt = 1; + break; + case 'v': + generation_opt = 1; + break; + default: + usage(); + } + + if (verbose) + fprintf (stderr, "lsctx %s (%s)\n", + E2FSPROGS_VERSION, E2FSPROGS_DATE); + if (optind > argc - 1) + lsctx_args ("."); + else + for (i = optind; i < argc; i++) + lsctx_args (argv[i]); + exit(0); +}