From de3e1dc1eae2d6bd6aa11c34290498d966885245 Mon Sep 17 00:00:00 2001 From: Enrico Scholz Date: Tue, 13 Jan 2004 13:46:35 +0000 Subject: [PATCH] initial checkin git-svn-id: http://svn.linux-vserver.org/svn/util-vserver/trunk@558 94cd875c-1c1d-0410-91d2-eb244daf1a30 --- util-vserver/lib/ioctl-getext2flags.c | 46 ++++++ util-vserver/lib/ioctl-getfilecontext.c | 37 +++++ util-vserver/lib/ioctl-setext2flags.c | 52 +++++++ util-vserver/lib/ioctl-setfilecontext.c | 36 +++++ util-vserver/src/chxid.c | 117 ++++++++++++++++ util-vserver/src/fstool.c | 241 ++++++++++++++++++++++++++++++++ util-vserver/src/fstool.h | 56 ++++++++ util-vserver/src/lsxid.c | 150 ++++++++++++++++++++ util-vserver/src/setattr.c | 133 ++++++++++++++++++ 9 files changed, 868 insertions(+) create mode 100644 util-vserver/lib/ioctl-getext2flags.c create mode 100644 util-vserver/lib/ioctl-getfilecontext.c create mode 100644 util-vserver/lib/ioctl-setext2flags.c create mode 100644 util-vserver/lib/ioctl-setfilecontext.c create mode 100644 util-vserver/src/chxid.c create mode 100644 util-vserver/src/fstool.c create mode 100644 util-vserver/src/fstool.h create mode 100644 util-vserver/src/lsxid.c create mode 100644 util-vserver/src/setattr.c diff --git a/util-vserver/lib/ioctl-getext2flags.c b/util-vserver/lib/ioctl-getext2flags.c new file mode 100644 index 0000000..1a532b1 --- /dev/null +++ b/util-vserver/lib/ioctl-getext2flags.c @@ -0,0 +1,46 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2004 Enrico Scholz +// +// This program 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; version 2 of the License. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "vserver.h" +#include "vserver-internal.h" +#include "ext2fs.h" + +#include + +#ifndef EXT2_IMMUTABLE_FILE_FL +# define EXT2_IMMUTABLE_FILE_FL 0x00000010 +#endif + +#ifndef EXT2_IMMUTABLE_LINK_FL +# define EXT2_IMMUTABLE_LINK_FL 0x00008000 +#endif + +int +vc_X_get_ext2flags(int fd, long *flags) +{ + int rc; + *flags = 0; + rc = ioctl(fd, EXT2_IOC_GETFLAGS, flags); + *flags = EXT2FLAGS_KERNEL2USER(*flags); + + return rc; +} diff --git a/util-vserver/lib/ioctl-getfilecontext.c b/util-vserver/lib/ioctl-getfilecontext.c new file mode 100644 index 0000000..f4f13e6 --- /dev/null +++ b/util-vserver/lib/ioctl-getfilecontext.c @@ -0,0 +1,37 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2004 Enrico Scholz +// +// This program 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; version 2 of the License. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "vserver.h" +#include "vserver-internal.h" +#include "ext2fs.h" + +#include + +xid_t +vc_X_get_filecontext(int fd) +{ + int c; + int rc = ioctl(fd, EXT2_IOC_GETCONTEXT, &c); + + if (rc==-1) return VC_NOCTX; + else return c; +} diff --git a/util-vserver/lib/ioctl-setext2flags.c b/util-vserver/lib/ioctl-setext2flags.c new file mode 100644 index 0000000..e006fcd --- /dev/null +++ b/util-vserver/lib/ioctl-setext2flags.c @@ -0,0 +1,52 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2004 Enrico Scholz +// +// This program 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; version 2 of the License. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "vserver.h" +#include "vserver-internal.h" +#include "ext2fs.h" + +#include + +#ifndef EXT2_IMMUTABLE_FILE_FL +# define EXT2_IMMUTABLE_FILE_FL 0x00000010 +#endif + +#ifndef EXT2_IMMUTABLE_LINK_FL +# define EXT2_IMMUTABLE_LINK_FL 0x00008000 +#endif + +int +vc_X_set_ext2flags(int fd, long set_flags, long del_flags) +{ + long old_flags = 0; + + set_flags = EXT2FLAGS_USER2KERNEL(set_flags); + del_flags = EXT2FLAGS_USER2KERNEL(del_flags); + + if (del_flags!=-1) { + if (ioctl(fd, EXT2_IOC_GETFLAGS, &old_flags)==-1) return -1; + old_flags &= ~del_flags; + } + + old_flags |= set_flags; + return ioctl(fd, EXT2_IOC_SETFLAGS, &old_flags); +} diff --git a/util-vserver/lib/ioctl-setfilecontext.c b/util-vserver/lib/ioctl-setfilecontext.c new file mode 100644 index 0000000..0f67997 --- /dev/null +++ b/util-vserver/lib/ioctl-setfilecontext.c @@ -0,0 +1,36 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2004 Enrico Scholz +// +// This program 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; version 2 of the License. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "vserver.h" +#include "vserver-internal.h" +#include "ext2fs.h" + +#include + +int +vc_X_set_filecontext(int fd, xid_t ctx) +{ + int c = ctx; + int rc = ioctl(fd, EXT2_IOC_SETCONTEXT, &c); + + return rc; +} diff --git a/util-vserver/src/chxid.c b/util-vserver/src/chxid.c new file mode 100644 index 0000000..e2b6fa8 --- /dev/null +++ b/util-vserver/src/chxid.c @@ -0,0 +1,117 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2004 Enrico Scholz +// +// This program 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; version 2 of the License. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "fstool.h" +#include "util.h" + +#include "lib/vserver.h" + +#include +#include +#include +#include +#include + +struct option const +CMDLINE_OPTIONS[] = { + { "help", no_argument, 0, CMD_HELP }, + { "version", no_argument, 0, CMD_VERSION }, + { 0,0,0,0 } +}; + +char const CMDLINE_OPTIONS_SHORT[] = "Rc:"; + +void +showHelp(int fd, char const *cmd, int res) +{ + WRITE_MSG(fd, "Usage: "); + WRITE_STR(fd, cmd); + WRITE_MSG(fd, + " -c [-R] [--] +\n\n" + " Options:\n" + " -R ... recurse through directories\n" + " -c ... assign the given context/vserver to the file(s)\n" + "Please report bugs to " PACKAGE_BUGREPORT "\n"); + exit(res); +} + +void +showVersion() +{ + WRITE_MSG(1, + "chxid " VERSION " -- assigns a context to a file\n" + "This program is part of " PACKAGE_STRING "\n\n" + "Copyright (C) 2004 Enrico Scholz\n" + VERSION_COPYRIGHT_DISCLAIMER); + exit(0); +} + +static bool +setFile(char const *name, char const * display_name, struct stat const *exp_st) +{ + bool res = false; + int fd = open(name, O_RDONLY); + + if (fd==-1) { + perror("open()"); + return false; + } + + if (!exp_st || + !checkForRace(fd, name, exp_st)) + goto err; + + if (vc_X_set_filecontext(fd, global_args->ctx)==-1) { + //perror("vc_X_set_filecontext()"); + perror(display_name); + goto err; + } + + res = true; + + err: + close(fd); + return res; +} + +bool +handleFile(char const *name, char const * display_name, + struct stat const *exp_st) +{ + if (S_ISLNK(exp_st->st_mode)) return true; + + return setFile(name, display_name, exp_st); +} + +void +checkParams(struct Arguments const UNUSED *args, int argc) +{ + if (optind==argc) { + WRITE_MSG(2, "No filename given; use '--help' for more information\n"); + exit(1); + } + + if (args->ctx==VC_NOCTX) { + WRITE_MSG(2, "No valid context given; use '--help' for more information\n"); + exit(1); + } +} diff --git a/util-vserver/src/fstool.c b/util-vserver/src/fstool.c new file mode 100644 index 0000000..780997f --- /dev/null +++ b/util-vserver/src/fstool.c @@ -0,0 +1,241 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2004 Enrico Scholz +// +// This program 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; version 2 of the License. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "fstool.h" +#include "util.h" +#include "wrappers.h" +#include "wrappers-dirent.h" + +#include + +#include +#include +#include + + +struct Arguments const * global_args = 0; + +int wrapper_exit_code = 1; + +bool +checkForRace(int fd, char const * name, struct stat const *exp_st) +{ + struct stat st; + + if (fstat(fd, &st)==-1) { + perror("fstat()"); + return false; + } + + if (st.st_dev != exp_st->st_dev || + st.st_ino != exp_st->st_ino || + st.st_mode != exp_st->st_mode) { + close(fd); + WRITE_MSG(2, "race while visiting '"); + WRITE_STR(2, name); + WRITE_MSG(2, "'\n"); + exit(2); + } + + return true; +} + +inline static bool +isSpecialDir(char const *d) +{ + return (d[0]=='.' && (d[1]=='\0' || (d[1]=='.' && d[2]=='\0'))); +} + +#define CONCAT_PATHS(LHS, LHS_LEN, RHS) \ + size_t l_rhs = strlen(RHS); \ + char new_path[(LHS_LEN) + l_rhs + sizeof("/")]; \ + memcpy(new_path, LHS, (LHS_LEN)); \ + memcpy(new_path+(LHS_LEN), "/", 1); \ + memcpy(new_path+(LHS_LEN)+1, RHS, l_rhs); \ + new_path[(LHS_LEN)+1+l_rhs] = '\0'; + +static uint64_t +iterateFilesystem(char const *path) +{ + bool do_again = false; + size_t path_len = strlen(path); + DIR * dir = Eopendir("."); + uint64_t err = 0; + + { + struct stat st; + if (lstat(".", &st)==-1) perror("lstat()"); + else err += handleFile(".", path, &st) ? 0 : 1; + } + + for (;;) { + struct dirent *ent = Ereaddir(dir); + struct stat st; + + if (ent==0) break; + if (isSpecialDir(ent->d_name)) continue; + + if (lstat(ent->d_name, &st)==-1) { + perror("lstat()"); + ++err; + continue; + } + + if (S_ISDIR(st.st_mode) && global_args->do_recurse) { + do_again = true; + continue; + } + + { + CONCAT_PATHS(path, path_len, ent->d_name); + err += handleFile(ent->d_name, new_path, &st) ? 0 : 1; + } + } + + if (do_again) { + int cur_dir = Eopen(".", O_RDONLY, 0); + rewinddir(dir); + + for (;;) { + struct dirent *ent = Ereaddir(dir); + struct stat st; + + if (ent==0) break; + if (isSpecialDir(ent->d_name)) continue; + + if (lstat(ent->d_name, &st)==-1) { + perror("lstat()"); + ++err; + continue; + } + + if (!S_ISDIR(st.st_mode)) continue; + safeChdir(ent->d_name, &st); + { + CONCAT_PATHS(path, path_len, ent->d_name); + err += iterateFilesystem(new_path); + } + Efchdir(cur_dir); + } + Eclose(cur_dir); + } + + Eclosedir(dir); + + return err; +} +#undef CONCAT_PATHS + +static uint64_t +processFile(char const *path) +{ + struct stat st; + + if (lstat(path, &st)==-1) { + perror("lstat()"); + return 1; + } + + if (S_ISDIR(st.st_mode) && !global_args->do_display_dir) + return iterateFilesystem(path); + else + return handleFile(path, path, &st); +} + +static xid_t +resolveCtx(char const *str) +{ + xid_t res; + + if (*str==':') ++str; + else { + char *end_ptr; + long result = strtol(str, &end_ptr, 0); + + if (end_ptr>str && *end_ptr==0) return result; + } + + res = vc_getVserverCtx(str, vcCFG_AUTO, true, 0); + if (res==VC_NOCTX) { + WRITE_MSG(2, "Can not find a vserver with name '"); + WRITE_STR(2, str); + WRITE_MSG(2, "', or vserver does not have a static context\n"); + exit(1); + } + + return res; +} + +int main(int argc, char *argv[]) +{ + uint64_t err_cnt = 0; + int i; + struct Arguments args = { + .do_recurse = false, + .do_display_dot = false, + .do_display_dir = false, + .do_mapping = true, + .immutable = false, + .immulink = false, + .ctx = VC_NOCTX, + .is_legacy = false, + .do_set = false, + .do_unset = false, + }; + + global_args = &args; + while (1) { + int c = getopt_long(argc, argv, CMDLINE_OPTIONS_SHORT, + CMDLINE_OPTIONS, 0); + if (c==-1) break; + + switch (c) { + case CMD_HELP : showHelp(1, argv[0], 0); + case CMD_VERSION : showVersion(); + case CMD_IMMUTABLE : args.immutable = true; break; + case CMD_IMMULINK : args.immulink = true; break; + case CMD_LEGACY : args.is_legacy = true; break; + case 'R' : args.do_recurse = true; break; + case 'a' : args.do_display_dot = true; break; + case 'd' : args.do_display_dir = true; break; + case 'n' : args.do_mapping = false; break; + case 's' : args.do_set = true; break; + case 'u' : args.do_unset = true; break; + case 'c' : args.ctx = resolveCtx(optarg); break; + default : + WRITE_MSG(2, "Try '"); + WRITE_STR(2, argv[0]); + WRITE_MSG(2, " --help\" for more information.\n"); + return EXIT_FAILURE; + break; + } + } + + checkParams(&args, argc); + + if (optind==argc) + err_cnt = processFile("."); + else for (i=optind; i0 ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/util-vserver/src/fstool.h b/util-vserver/src/fstool.h new file mode 100644 index 0000000..73a7f21 --- /dev/null +++ b/util-vserver/src/fstool.h @@ -0,0 +1,56 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2004 Enrico Scholz +// +// This program 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; version 2 of the License. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +#ifndef H_UTIL_VSERVER_SRC_FSTOOL_H +#define H_UTIL_VSERVER_SRC_FSTOOL_H + +#include +#include + +#define CMD_HELP 0x8000 +#define CMD_VERSION 0x8001 +#define CMD_IMMUTABLE 0x8002 +#define CMD_IMMULINK 0x8003 +#define CMD_LEGACY 0x8004 + +struct stat; + +struct Arguments { + bool do_recurse; + bool do_display_dot; + bool do_display_dir; + bool do_mapping; + bool immutable; + bool immulink; + xid_t ctx; + bool is_legacy; + bool do_set; + bool do_unset; +}; + +extern struct option const CMDLINE_OPTIONS[]; +extern char const CMDLINE_OPTIONS_SHORT[]; +extern struct Arguments const * global_args; + +bool checkForRace(int fd, char const * name, struct stat const *exp_st); +void checkParams(struct Arguments const *, int argc); +bool handleFile(char const *d_name, char const *full_name, struct stat const *); +void showHelp(int fd, char const *cmd, int res); +void showVersion(); + +#endif // H_UTIL_VSERVER_SRC_FSTOOL_H diff --git a/util-vserver/src/lsxid.c b/util-vserver/src/lsxid.c new file mode 100644 index 0000000..d6bd531 --- /dev/null +++ b/util-vserver/src/lsxid.c @@ -0,0 +1,150 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2004 Enrico Scholz +// +// This program 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; version 2 of the License. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "fstool.h" +#include "util.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +struct option const +CMDLINE_OPTIONS[] = { + { "help", no_argument, 0, CMD_HELP }, + { "version", no_argument, 0, CMD_VERSION }, + { 0,0,0,0 } +}; + +char const CMDLINE_OPTIONS_SHORT[] = "Radn"; + +void +showHelp(int fd, char const *cmd, int res) +{ + WRITE_MSG(fd, "Usage: "); + WRITE_STR(fd, cmd); + WRITE_MSG(fd, + " [-Radn] [--] *\n\n" + " Options:\n" + " -R ... recurse through directories\n" + " -a ... display files starting with '.' also\n" + " -d ... list directories like other files instead of\n" + " listing their content\n" + " -n ... do not try to do xid -> vserver-name mapping\n" + "Please report bugs to " PACKAGE_BUGREPORT "\n"); + exit(res); +} + +void +showVersion() +{ + WRITE_MSG(1, + "lsxid " VERSION " -- shows the context which is associated to a file\n" + "This program is part of " PACKAGE_STRING "\n\n" + "Copyright (C) 2004 Enrico Scholz\n" + VERSION_COPYRIGHT_DISCLAIMER); + exit(0); +} + +void +checkParams(struct Arguments const UNUSED * args, int UNUSED argc) +{ +} + +static xid_t +getFileContext(char const *name, struct stat const *exp_st) +{ + int fd = open(name, O_RDONLY); + xid_t res; + + if (fd==-1) { + perror("open()"); + return VC_NOCTX; + } + + if (exp_st) + checkForRace(fd, name, exp_st); + + res = vc_X_get_filecontext(fd); + if (res==VC_NOCTX) + perror("vc_X_get_filecontext()"); + + close(fd); + + return res; +} + +bool +handleFile(char const *name, char const *display_name, + struct stat const *exp_st) +{ + xid_t ctx = 0; + char buf[MAX(sizeof(ctx)*3+1, 20)]; + bool need_write = true; + + memset(buf, ' ', sizeof buf); + + if (S_ISLNK(exp_st->st_mode)) { + memcpy(buf, "-------", 7); + write(1, buf, sizeof buf); + need_write = false; + } + else { + ctx = getFileContext(name, exp_st); + + if (ctx==VC_NOCTX) { + memcpy(buf, "!!ERR!!", 7); + write(1, buf, sizeof buf); + need_write = false; + } + else if (global_args->do_mapping) { + char const * vname = vc_getVserverByCtx(ctx, 0,0); + if (!vname) buf[0] = '\0'; + else { + size_t l = strlen(vname); + if (l +// +// This program 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; version 2 of the License. +// +// This program 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "fstool.h" +#include "util.h" + +#include +#include +#include + +#include +#include +#include +#include + + +struct option const +CMDLINE_OPTIONS[] = { + { "help", no_argument, 0, CMD_HELP }, + { "version", no_argument, 0, CMD_VERSION }, + { "immutable", no_argument, 0, CMD_IMMUTABLE }, + { "immulink", no_argument, 0, CMD_IMMULINK }, + { 0,0,0,0 } +}; + +char const CMDLINE_OPTIONS_SHORT[] = "Rsu"; + +static long set_mask = 0; +static long del_mask = VC_IMMUTABLE_ALL; + +void +showHelp(int fd, char const *cmd, int res) +{ + WRITE_MSG(fd, "Usage: "); + WRITE_STR(fd, cmd); + WRITE_MSG(fd, + " [-Rsu] [--immutable] [--immulink] [--] +\n\n" + " Options:\n" + " -R ... recurse through directories\n" + " -s ... set flag only; when only one of the '--immu*' options\n" + " is given, do not delete the other ones\n" + " -u ... revert operation and unset the given flags\n" + "Please report bugs to " PACKAGE_BUGREPORT "\n"); + exit(res); +} + +void +showVersion() +{ + WRITE_MSG(1, + "setattr " VERSION " -- sets vserver specific file attributes\n" + "This program is part of " PACKAGE_STRING "\n\n" + "Copyright (C) 2004 Enrico Scholz\n" + VERSION_COPYRIGHT_DISCLAIMER); + exit(0); +} + +void +checkParams(struct Arguments const * args, int argc) +{ + if (optind==argc) { + WRITE_MSG(2, "No filename given; use '--help' for more information\n"); + exit(1); + } + + set_mask = 0; + if (args->immutable) set_mask |= VC_IMMUTABLE_FILE_FL; + if (args->immulink) set_mask |= VC_IMMUTABLE_LINK_FL; + + if (args->do_set) del_mask = 0; + else del_mask = VC_IMMUTABLE_ALL; + + if (args->do_unset) { + del_mask = set_mask; + set_mask = 0; + } +} + +static bool +setFlags(char const *name, char const *display_name, + struct stat const *exp_st) +{ + int fd = open(name, O_RDONLY); + int res = false; + + if (fd==-1) { + perror("open()"); + return false; + } + + if (!exp_st || + !checkForRace(fd, name, exp_st)) + goto err; + + if (vc_X_set_ext2flags(fd, set_mask, del_mask)==-1) { + perror(display_name); + goto err; + } + + res = true; + + err: + close(fd); + return res; +} + +bool +handleFile(char const *name, char const * display_name, + struct stat const *exp_st) +{ + if (S_ISLNK(exp_st->st_mode)) return true; + + return setFlags(name, display_name, exp_st); +} -- 1.8.1.5