initial checkin
authorEnrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
Tue, 13 Jan 2004 13:46:35 +0000 (13:46 +0000)
committerEnrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
Tue, 13 Jan 2004 13:46:35 +0000 (13:46 +0000)
git-svn-id: http://svn.linux-vserver.org/svn/util-vserver/trunk@558 94cd875c-1c1d-0410-91d2-eb244daf1a30

util-vserver/lib/ioctl-getext2flags.c [new file with mode: 0644]
util-vserver/lib/ioctl-getfilecontext.c [new file with mode: 0644]
util-vserver/lib/ioctl-setext2flags.c [new file with mode: 0644]
util-vserver/lib/ioctl-setfilecontext.c [new file with mode: 0644]
util-vserver/src/chxid.c [new file with mode: 0644]
util-vserver/src/fstool.c [new file with mode: 0644]
util-vserver/src/fstool.h [new file with mode: 0644]
util-vserver/src/lsxid.c [new file with mode: 0644]
util-vserver/src/setattr.c [new file with mode: 0644]

diff --git a/util-vserver/lib/ioctl-getext2flags.c b/util-vserver/lib/ioctl-getext2flags.c
new file mode 100644 (file)
index 0000000..1a532b1
--- /dev/null
@@ -0,0 +1,46 @@
+// $Id$    --*- c -*--
+
+// Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+//  
+// 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 <config.h>
+#endif
+
+#include "vserver.h"
+#include "vserver-internal.h"
+#include "ext2fs.h"
+
+#include <sys/ioctl.h>
+
+#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 (file)
index 0000000..f4f13e6
--- /dev/null
@@ -0,0 +1,37 @@
+// $Id$    --*- c -*--
+
+// Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+//  
+// 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 <config.h>
+#endif
+
+#include "vserver.h"
+#include "vserver-internal.h"
+#include "ext2fs.h"
+
+#include <sys/ioctl.h>
+
+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 (file)
index 0000000..e006fcd
--- /dev/null
@@ -0,0 +1,52 @@
+// $Id$    --*- c -*--
+
+// Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+//  
+// 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 <config.h>
+#endif
+
+#include "vserver.h"
+#include "vserver-internal.h"
+#include "ext2fs.h"
+
+#include <sys/ioctl.h>
+
+#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 (file)
index 0000000..0f67997
--- /dev/null
@@ -0,0 +1,36 @@
+// $Id$    --*- c -*--
+
+// Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+//  
+// 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 <config.h>
+#endif
+
+#include "vserver.h"
+#include "vserver-internal.h"
+#include "ext2fs.h"
+
+#include <sys/ioctl.h>
+
+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 (file)
index 0000000..e2b6fa8
--- /dev/null
@@ -0,0 +1,117 @@
+// $Id$    --*- c -*--
+
+// Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+//  
+// 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 <config.h>
+#endif
+
+#include "fstool.h"
+#include "util.h"
+
+#include "lib/vserver.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+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 <ctx|vserver> [-R] [--] <file>+\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 (file)
index 0000000..780997f
--- /dev/null
@@ -0,0 +1,241 @@
+// $Id$    --*- c -*--
+
+// Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+//  
+// 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 <config.h>
+#endif
+
+#include "fstool.h"
+#include "util.h"
+#include "wrappers.h"
+#include "wrappers-dirent.h"
+
+#include <lib/vserver.h>
+
+#include <getopt.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+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; i<argc; ++i)
+    err_cnt += processFile(argv[i]);
+
+  return err_cnt>0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}
diff --git a/util-vserver/src/fstool.h b/util-vserver/src/fstool.h
new file mode 100644 (file)
index 0000000..73a7f21
--- /dev/null
@@ -0,0 +1,56 @@
+// $Id$    --*- c -*--
+
+// Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+//  
+// 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 <getopt.h>
+#include <stdbool.h>
+
+#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 (file)
index 0000000..d6bd531
--- /dev/null
@@ -0,0 +1,150 @@
+// $Id$    --*- c -*--
+
+// Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+//  
+// 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 <config.h>
+#endif
+
+#include "fstool.h"
+#include "util.h"
+
+#include <lib/vserver.h>
+#include <lib/vserver-internal.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+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] [--] <file>*\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<sizeof(buf)) write(1, buf, sizeof(buf)-l);
+       write(1, vname, l);
+
+       free((char *)vname);
+       need_write = false;
+      }
+    }
+  }
+
+  if (need_write) {
+    size_t     l = utilvserver_fmt_ulong(buf, ctx);
+    if (l<sizeof(buf)) write(1, buf+l, sizeof(buf)-l);
+    write(1, buf, l);
+  }
+
+  write(1, "  ", 2);
+  write(1, display_name, strlen(display_name));
+  write(1, "\n", 1);
+
+  return ctx!=VC_NOCTX;
+}
diff --git a/util-vserver/src/setattr.c b/util-vserver/src/setattr.c
new file mode 100644 (file)
index 0000000..4d4ba91
--- /dev/null
@@ -0,0 +1,133 @@
+// $Id$    --*- c -*--
+
+// Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+//  
+// 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 <config.h>
+#endif
+
+#include "fstool.h"
+#include "util.h"
+
+#include <lib/fmt.h>
+#include <lib/vserver.h>
+#include <lib/vserver-internal.h>
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+
+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] [--] <file>+\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);
+}