- sync to util-vserver-0.30.208
authorMark Huang <mlhuang@cs.princeton.edu>
Sun, 21 Aug 2005 22:17:13 +0000 (22:17 +0000)
committerMark Huang <mlhuang@cs.princeton.edu>
Sun, 21 Aug 2005 22:17:13 +0000 (22:17 +0000)
lib/syscall_setsched-v13.hc
lib/syscall_setsched.c
src/chcontext.c
src/showattr.c
src/vdu.c

index 02284e0..83c2af7 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: syscall_setsched-v13.hc,v 1.4 2004/10/19 21:04:23 ensc Exp $    --*- c -*--
+// $Id$    --*- c -*--
 
 // Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
 //  
 #endif
 
 #include "vserver.h"
-#include "sched_cmd.h"
+#include <lib_internal/util.h>
 
 #define VCGET(MASK,VAL)                ((data->set_mask & (MASK)) ? (VAL) : SCHED_KEEP);
 
-
 static inline ALWAYSINLINE int
 vc_set_sched_v13obs(xid_t xid, struct vc_set_sched const *data)
 {
@@ -55,7 +54,7 @@ vc_set_sched_v13b(xid_t xid, struct vc_set_sched const *data)
       X(set_mask)   && X(fill_rate)  && X(interval)   && X(tokens) &&
       X(tokens_min) && X(tokens_max) && X(priority_bias))
     return vserver(VCMD_set_sched, CTX_USER2KERNEL(xid),
-                  (struct vc_set_sched *)(data));
+                  const_cast(struct vc_set_sched *)(data));
   else {
     k_data.set_mask      = data->set_mask;
     k_data.fill_rate     = data->fill_rate;
index 5884fc0..94a6a9f 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: syscall_setsched.c,v 1.2 2004/09/22 20:45:37 ensc Exp $    --*- c -*--
+// $Id$    --*- c -*--
 
 // Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
 //  
 #ifdef HAVE_CONFIG_H
 #  include <config.h>
 #endif
-#include "compat.h"
 
 #include "vserver.h"
+#include "linuxvirtual.h"
 
 #define VC_MULTIVERSION_SYSCALL        1
 #include "vserver-internal.h"
 
-#include "linuxvirtual.h"
-
-#define VC_ENABLE_API_V13
-
 #ifdef VC_ENABLE_API_V13
 #  include "syscall_setsched-v13.hc"
 #endif
index 1b5275a..fe66a22 100644 (file)
@@ -1,6 +1,6 @@
-// $Id: chcontext.c,v 1.1.4.3 2004/01/07 16:24:01 ensc Exp $
+// $Id: chcontext.c,v 1.24 2005/03/22 15:05:24 ensc Exp $
 
-// Copyright (C) 2003 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+// Copyright (C) 2003,2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
 // based on chcontext.cc by Jacques Gelinas
 //  
 // This program is free software; you can redistribute it and/or modify
 #ifdef HAVE_CONFIG_H
 #  include <config.h>
 #endif
-#include "compat.h"
+
+#include "util.h"
+#include "vserver.h"
+#include "internal.h"
+#include "lib_internal/jail.h"
 
 #include <stdio.h>
 #include <unistd.h>
 #include <string.h>
 #include <stdlib.h>
 #include <errno.h>
+#include <getopt.h>
+#include <assert.h>
+#include <fcntl.h>
+#include <libgen.h>
+#include <signal.h>
 
-#include "linuxcaps.h"
-#include "vserver.h"
+#define ENSC_WRAPPERS_PREFIX   "chcontext: "
+#define ENSC_WRAPPERS_VSERVER  1
+#define ENSC_WRAPPERS_UNISTD   1
+#define ENSC_WRAPPERS_FCNTL    1
+#include <wrappers.h>
 
-#ifndef CAP_QUOTACTL
-#  define CAP_QUOTACTL 29
-#endif
+#define CMD_HELP       0x1000
+#define CMD_VERSION    0x1001
+#define CMD_CAP                0x4000
+#define CMD_CTX                0x4001
+#define CMD_DISCONNECT 0x4002
+#define CMD_DOMAINNAME 0x4003
+#define CMD_FLAG       0x4004
+#define CMD_HOSTNAME   0x4005
+#define CMD_SECURE     0x4006
+#define CMD_SILENT     0x4007
+
+int wrapper_exit_code  = 255;
+
+struct option const
+CMDLINE_OPTIONS[] = {
+  { "help",     no_argument,  0, CMD_HELP },
+  { "version",  no_argument,  0, CMD_VERSION },
+  { "cap",        required_argument,  0, CMD_CAP },
+  { "ctx",        required_argument,  0, CMD_CTX },
+  { "xid",        required_argument,  0, CMD_CTX },
+  { "disconnect", no_argument,        0, CMD_DISCONNECT },
+  { "domainname", required_argument,  0, CMD_DOMAINNAME },
+  { "flag",       required_argument,  0, CMD_FLAG },
+  { "hostname",   required_argument,  0, CMD_HOSTNAME },
+  { "secure",     no_argument,        0, CMD_SECURE },
+  { "silent",     no_argument,        0, CMD_SILENT },
+  { 0,0,0,0 }
+};
+
+struct Arguments {
+    size_t             nbctx;
+    xid_t              ctxs[16];
+    bool               do_disconnect;
+    bool               do_silent;
+    unsigned int       flags;
+    uint32_t           remove_caps;
+    uint32_t           add_caps;
+    char const *       hostname;
+    char const *       domainname;
+};
+
+static struct Arguments const *                global_args = 0;
+
+static void
+showHelp(int fd, char const *cmd, int res)
+{
+  VSERVER_DECLARE_CMD(cmd);
+  
+  WRITE_MSG(fd, "Usage: ");
+  WRITE_STR(fd, cmd);
+  WRITE_MSG(fd,
+           " [--cap [!]<cap_name>] [--secure] [--xid <num>] [--disconnect]\n"
+           "       [--domainname <name>] [--hostname <name>] [--flag <flags>+]\n"
+           "       [--silent] [--] command arguments ...\n"
+           "\n"
+           "chcontext allocate a new security context and executes\n"
+           "a command in that context.\n"
+           "By default, a new/unused context is allocated\n"
+           "\n"
+           "--cap CAP_NAME\n"
+           "    Add a capability from the command. This option may be\n"
+           "    repeated several time.\n"
+           "    See /usr/include/linux/capability.h\n"
+           "    In general, this option is used with the --secure option\n"
+           "    --secure removes most critical capabilities and --cap\n"
+           "    adds specific ones.\n"
+           "\n"
+
+           "--cap !CAP_NAME\n"
+           "    Remove a capability from the command. This option may be\n"
+           "    repeated several time.\n"
+           "    See /usr/include/linux/capability.h\n"
+           "\n"
+           "--xid num\n"
+           "    Select the context. On root in context 0 is allowed to\n"
+           "    select a specific context.\n"
+           "    Context number 1 is special. It can see all processes\n"
+           "    in any contexts, but can't kill them though.\n"
+           "    Option --xid may be repeated several times to specify up to 16 contexts.\n"
+
+           "--disconnect\n"
+           "    Start the command in background and make the process\n"
+           "    a child of process 1.\n"
+
+           "--domainname new_domainname\n"
+           "    Set the domainname (NIS) in the new security context.\n"
+           "    Use \"none\" to unset the domain name.\n"
+
+           "--flag\n"
+           "    Set one flag in the new or current security context. The following\n"
+           "    flags are supported. The option may be used several time.\n"
+           "\n"
+           "        fakeinit: The new process will believe it is process number 1.\n"
+           "                  Useful to run a real /sbin/init in a vserver.\n"
+           "        lock:     The new process is trapped and can't use chcontext anymore.\n"
+           "        sched:    The new process and its children will share a common \n"
+           "                  execution priority.\n"
+           "        nproc:    Limit the number of process in the vserver according to\n"
+           "                  ulimit setting. Normally, ulimit is a per user thing.\n"
+           "                  With this flag, it becomes a per vserver thing.\n"
+           "        private:  No one can join this security context once created.\n"
+           "        ulimit:   Apply the current ulimit to the whole context\n"
+
+           "--hostname new_hostname\n"
+           "    Set the hostname in the new security context\n"
+           "    This is need because if you create a less privileged\n"
+           "    security context, it may be unable to change its hostname\n"
+
+           "--secure\n"
+           "    Remove all the capabilities to make a virtual server trustable\n"
+
+           "--silent\n"
+           "    Do not print the allocated context number.\n"
+           "\n"
+           "Please report bugs to " PACKAGE_BUGREPORT "\n");
+
+  exit(res);
+}
+
+static void
+showVersion()
+{
+  WRITE_MSG(1,
+           "chcontext-compat " VERSION " -- allocates/enters a security context\n"
+           "This program is part of " PACKAGE_STRING "\n\n"
+           "Copyright (C) 2003,2004 Enrico Scholz\n"
+           VERSION_COPYRIGHT_DISCLAIMER);
+  exit(0);
+}
+
+static inline void
+setCap(char const *str, uint32_t *add_caps, uint32_t *remove_caps)
+{
+  uint32_t     *cap;
+  int          bit;
+  
+  if (str[0] != '!')
+    cap = add_caps;
+  else {
+    cap = remove_caps;
+    str++;
+  }
+       
+  bit = vc_text2cap(str);
+       
+  if (bit!=-1) *cap |= (1<<bit);
+  else {
+    WRITE_MSG(2, "Unknown capability '");
+    WRITE_STR(2, str);
+    WRITE_MSG(2, "'\n");
+    exit(wrapper_exit_code);
+  }
+}
+
+static inline void
+setFlags(char const *str, uint32_t *flags)
+{
+  struct vc_err_listparser     err;
+  
+  *flags = vc_list2cflag_compat(str, 0, &err);
 
-static void usage()
+  if (err.ptr!=0) {
+    WRITE_MSG(2, "Unknown flag '");
+    Vwrite(2, err.ptr, err.len);
+    WRITE_MSG(2, "'\n");
+    exit(wrapper_exit_code);
+  }
+}
+
+static inline ALWAYSINLINE void
+setHostname(char const *name)
+{
+  if (name == NULL) return;
+  
+  if (sethostname(name, strlen(name))==-1) {
+    perror("chcontext: sethostname()");
+    exit(255);
+  }
+  if (!global_args->do_silent) {
+    WRITE_MSG(1, "Host name is now ");
+    WRITE_STR(1, name);
+    WRITE_MSG(1, "\n");
+  }
+}
+
+static inline ALWAYSINLINE void
+setDomainname(char const *name)
+{
+  if (name == NULL) return;
+  
+  if (setdomainname(name, strlen(name))==-1) {
+    perror("chcontext: setdomainname()");
+    exit(255);
+  }
+  if (!global_args->do_silent) {
+    WRITE_MSG(1, "Domain name is now ");
+    WRITE_STR(1, name);
+    WRITE_MSG(1, "\n");
+  }
+}
+
+static inline ALWAYSINLINE void
+tellContext(xid_t ctx)
 {
-       fprintf (stderr,"chcontext version %s\n",VERSION);
-       fprintf (stderr
-               ,"chcontext [ options ] command arguments ...\n"
-                "\n"
-                "chcontext allocate a new security context and executes\n"
-                "a command in that context.\n"
-                "By default, a new/unused context is allocated\n"
-                "\n"
-
-                "--cap CAP_NAME\n"
-                "\tAdd a capability from the command. This option may be\n"
-                "\trepeated several time.\n"
-                "\tSee /usr/include/linux/capability.h\n"
-                "\tIn general, this option is used with the --secure option\n"
-                "\t--secure removes most critical capabilities and --cap\n"
-                "\tadds specific ones.\n"
-                "\n"
-
-                "--cap !CAP_NAME\n"
-                "\tRemove a capability from the command. This option may be\n"
-                "\trepeated several time.\n"
-                "\tSee /usr/include/linux/capability.h\n"
-                "\n"
-                "--ctx num\n"
-                "\tSelect the context. On root in context 0 is allowed to\n"
-                "\tselect a specific context.\n"
-                "\tContext number 1 is special. It can see all processes\n"
-                "\tin any contexts, but can't kill them though.\n"
-                "\tOption --ctx may be repeated several times to specify up to 16 contexts.\n"
-
-                "--disconnect\n"
-                "\tStart the command in background and make the process\n"
-                "\ta child of process 1.\n"
-
-                "--domainname new_domainname\n"
-                "\tSet the domainname (NIS) in the new security context.\n"
-                "\tUse \"none\" to unset the domain name.\n"
-
-                "--flag\n"
-                "\tSet one flag in the new or current security context. The following\n"
-                "\tflags are supported. The option may be used several time.\n"
-                "\n"
-                "\tfakeinit: The new process will believe it is process number 1.\n"
-                "            Useful to run a real /sbin/init in a vserver.\n"
-                "\tlock: The new process is trapped and can't use chcontext anymore.\n"
-                "\tsched: The new process and its children will share a common \n"
-                "         execution priority.\n"
-                "\tnproc: Limit the number of process in the vserver according to\n"
-                "         ulimit setting. Normally, ulimit is a per user thing.\n"
-                "         With this flag, it becomes a per vserver thing.\n"
-                "\tprivate: No one can join this security context once created.\n"
-                "\tulimit: Apply the current ulimit to the whole context\n"
-
-                "--hostname new_hostname\n"
-                "\tSet the hostname in the new security context\n"
-                "\tThis is need because if you create a less privileged\n"
-                "\tsecurity context, it may be unable to change its hostname\n"
-
-                "--secure\n"
-                "\tRemove all the capabilities to make a virtual server trustable\n"
-
-                "--silent\n"
-                "\tDo not print the allocated context number.\n"
-                "\n"
-                "Information about context is found in /proc/self/status\n");
+  char         buf[sizeof(xid_t)*3+2];
+  size_t       l;
+
+  if (global_args->do_silent) return;
+
+  l = utilvserver_fmt_long(buf,ctx);
+
+  WRITE_MSG(1, "New security context is ");
+  Vwrite(1, buf, l);
+  WRITE_MSG(1, "\n");
 }
 
+#include "context-sync.hc"
 
 int main (int argc, char *argv[])
 {
-       int ret = -1;
-       int i;
-       int nbctx = 0;
-       int ctxs[16];
-       int disconnect = 0;
-       int silent = 0;
-       int flags = 0;
-       unsigned remove_cap = 0;
-       unsigned add_cap = 0;
-       unsigned long secure = (1<<CAP_LINUX_IMMUTABLE)
-               |(1<<CAP_NET_BIND_SERVICE)
-               |(1<<CAP_NET_BROADCAST)
-               |(1<<CAP_NET_ADMIN)
-               |(1<<CAP_NET_RAW)
-               |(1<<CAP_IPC_LOCK)
-               |(1<<CAP_IPC_OWNER)
-               |(1<<CAP_SYS_MODULE)
-               |(1<<CAP_SYS_RAWIO)
-               |(1<<CAP_SYS_PACCT)
-               |(1<<CAP_SYS_ADMIN)
-               |(1<<CAP_SYS_BOOT)
-               |(1<<CAP_SYS_NICE)
-               |(1<<CAP_SYS_RESOURCE)
-               |(1<<CAP_SYS_TIME)
-               |(1<<CAP_MKNOD)
-               |(1<<CAP_QUOTACTL);
-       const char *hostname=NULL, *domainname=NULL;
-
-       for (i=1; i<argc; i++){
-               const char *arg = argv[i];
-               const char *opt = argv[i+1];
-               if (strcmp(arg,"--ctx")==0){
-                       if (nbctx >= 16){
-                               fprintf (stderr,"Too many context, max 16, ignored.\n");
-                       }else{
-                               ctxs[nbctx++] = atoi(opt);
-                       }
-                       i++;
-               }else if (strcmp(arg,"--disconnect")==0){
-                       disconnect = 1;
-               }else if (strcmp(arg,"--silent")==0){
-                       silent = 1;
-               }else if (strcmp(arg,"--flag")==0){
-                       if (strcmp(opt,"lock")==0){
-                               flags |= 1;
-                       }else if (strcmp(opt,"sched")==0){
-                               flags |= 2;
-                       }else if (strcmp(opt,"nproc")==0){
-                               flags |= 4;
-                       }else if (strcmp(opt,"private")==0){
-                               flags |= 8;
-                       }else if (strcmp(opt,"fakeinit")==0){
-                               flags |= 16;
-                       }else if (strcmp(opt,"hideinfo")==0){
-                               flags |= 32;
-                       }else if (strcmp(opt,"ulimit")==0){
-                               flags |= 64;
-                       }else{
-                               fprintf (stderr,"Unknown flag %s\n",opt);
-                       }
-                       i++;
-               }else if (strcmp(arg,"--cap")==0){
-                       static struct {
-                               const char *option;
-                               int bit;
-                       }tbcap[]={
-                               // The following capabilities are normally available
-                               // to vservers administrator, but are place for
-                               // completeness
-                               {"CAP_CHOWN",CAP_CHOWN},
-                               {"CAP_DAC_OVERRIDE",CAP_DAC_OVERRIDE},
-                               {"CAP_DAC_READ_SEARCH",CAP_DAC_READ_SEARCH},
-                               {"CAP_FOWNER",CAP_FOWNER},
-                               {"CAP_FSETID",CAP_FSETID},
-                               {"CAP_KILL",CAP_KILL},
-                               {"CAP_SETGID",CAP_SETGID},
-                               {"CAP_SETUID",CAP_SETUID},
-                               {"CAP_SETPCAP",CAP_SETPCAP},
-                               {"CAP_SYS_TTY_CONFIG",CAP_SYS_TTY_CONFIG},
-                               {"CAP_LEASE",CAP_LEASE},
-                               {"CAP_SYS_CHROOT",CAP_SYS_CHROOT},
-
-                               // Those capabilities are not normally available
-                               // to vservers because they are not needed and
-                               // may represent a security risk
-                               {"CAP_LINUX_IMMUTABLE",CAP_LINUX_IMMUTABLE},
-                               {"CAP_NET_BIND_SERVICE",CAP_NET_BIND_SERVICE},
-                               {"CAP_NET_BROADCAST",CAP_NET_BROADCAST},
-                               {"CAP_NET_ADMIN",       CAP_NET_ADMIN},
-                               {"CAP_NET_RAW", CAP_NET_RAW},
-                               {"CAP_IPC_LOCK",        CAP_IPC_LOCK},
-                               {"CAP_IPC_OWNER",       CAP_IPC_OWNER},
-                               {"CAP_SYS_MODULE",CAP_SYS_MODULE},
-                               {"CAP_SYS_RAWIO",       CAP_SYS_RAWIO},
-                               {"CAP_SYS_PACCT",       CAP_SYS_PACCT},
-                               {"CAP_SYS_ADMIN",       CAP_SYS_ADMIN},
-                               {"CAP_SYS_BOOT",        CAP_SYS_BOOT},
-                               {"CAP_SYS_NICE",        CAP_SYS_NICE},
-                               {"CAP_SYS_RESOURCE",CAP_SYS_RESOURCE},
-                               {"CAP_SYS_TIME",        CAP_SYS_TIME},
-                               {"CAP_MKNOD",           CAP_MKNOD},
-                               {"CAP_QUOTACTL",        CAP_QUOTACTL},
-                               {NULL,0}
-                       };
-                       int j;
-                       unsigned *cap = &add_cap;
-                       if (opt[0] == '!'){
-                               cap = &remove_cap;
-                               opt++;
-                       }
-                       for (j=0; tbcap[j].option != NULL; j++){
-                               if (strcasecmp(tbcap[j].option,opt)==0){
-                                       *cap |= (1<<tbcap[j].bit);
-                                       break;
-                               }
-                       }
-                       if (tbcap[j].option == NULL){
-                               fprintf (stderr,"Unknown capability %s\n",opt);
-                       }
-                       i++;
-               }else if (strcmp(arg,"--secure")==0){
-                       remove_cap |= secure;
-               }else if (strcmp(arg,"--hostname")==0){
-                       hostname = opt;
-                       i++;
-               }else if (strcmp(arg,"--domainname")==0){
-                       if (opt != NULL && strcmp(opt,"none")==0) opt = "";
-                       domainname = opt;
-                       i++;
-               }else{
-                       break;
-               }
-       }
-       if (i == argc){
-               usage();
-       }else if (argv[i][0] == '-'){
-               usage();
-       }else{
-               /*
-                       We must fork early because fakeinit set the current
-                       process as the special init process
-               */
-               if (disconnect == 0 || fork()==0){
-                       int newctx;
-                       int xflags = flags & 16;
-
-                       if (nbctx == 0) ctxs[nbctx++] = -1;
-                       newctx = vc_new_s_context(ctxs[0],0,flags&~16);
-                       if (newctx != -1){
-                               if (hostname != NULL){
-                                       if (sethostname (hostname,strlen(hostname))==-1){
-                                               fprintf (stderr,"Can't set the host name (%s)\n"
-                                                       ,strerror(errno));
-                                       }else if (!silent){
-                                               printf ("Host name is now %s\n",hostname);
-                                       }
-                               }
-                               if (domainname != NULL){
-                                       setdomainname (domainname,strlen(domainname));
-                                       if (!silent){
-                                               printf ("Domain name is now %s\n",domainname);
-                                       }
-                               }
-                               remove_cap &= (~add_cap);
-                               if (remove_cap!=0 || xflags!=0)
-                                       vc_new_s_context (-2,remove_cap,xflags);
-                               if (!silent){
-                                       printf ("New security context is %d\n"
-                                               ,ctxs[0] == -1 ? newctx : ctxs[0]);
-                               }
-                               execvp (argv[i],argv+i);
-                               fprintf (stderr,"Can't exec %s (%s)\n",argv[i]
-                                       ,strerror(errno));
-                       }else{
-                               perror ("Can't set the new security context\n");
-                       }
-                       if (disconnect != 0) _exit(0);
-               }
+  struct Arguments args = {
+    .nbctx         = 0,
+    .do_disconnect = false,
+    .do_silent     = false,
+    .flags         = 0,
+    .remove_caps   = 0,
+    .add_caps      = 0,
+    .hostname      = 0,
+    .domainname    = 0
+  };
+  xid_t                newctx;
+  int          xflags;
+  int          p[2][2];
+  pid_t                pid;
+  
+  global_args = &args;
+  signal(SIGCHLD, SIG_DFL);
+
+  while (1) {
+    int                c = getopt_long(argc, argv, "+", CMDLINE_OPTIONS, 0);
+    if (c==-1) break;
+
+    switch (c) {
+      case CMD_HELP            :  showHelp(1, argv[0], 0);
+      case CMD_VERSION         :  showVersion();
+      case CMD_DISCONNECT      :  args.do_disconnect = true;   break;
+      case CMD_SILENT          :  args.do_silent     = true;   break;
+      case CMD_DOMAINNAME      :  args.domainname    = optarg; break;
+      case CMD_HOSTNAME                :  args.hostname      = optarg; break;
+       
+      case CMD_CAP             :
+       setCap(optarg, &args.add_caps, &args.remove_caps);
+       break;
+      case CMD_SECURE          :
+       args.remove_caps |= vc_get_insecurebcaps();
+       break;
+      case CMD_FLAG            :
+       setFlags(optarg, &args.flags);
+       break;
+      case CMD_CTX             :
+       if (args.nbctx>0)
+         WRITE_MSG(2, "WARNING: More than one ctx not supported by this version\n");
+       if (args.nbctx>=DIM_OF(args.ctxs)) {
+         WRITE_MSG(2, "Too many contexts given\n");
+         exit(255);
        }
-       return ret;
+       args.ctxs[args.nbctx++] = Evc_xidopt2xid(optarg, true);
+       break;
+
+         
+      default          :
+       WRITE_MSG(2, "Try '");
+       WRITE_STR(2, argv[0]);
+       WRITE_MSG(2, " --help\" for more information.\n");
+       return 255;
+       break;
+    }
+  }
+
+  if (optind>=argc) {
+    WRITE_MSG(2, "No command given; use '--help' for more information.\n");
+    exit(255);
+  }
+  
+  if (args.domainname && strcmp(args.domainname, "none")==0)
+    args.domainname = "";
+    
+  if (args.nbctx == 0)
+    args.ctxs[args.nbctx++] = VC_DYNAMIC_XID;
+    
+  xflags      = args.flags & S_CTX_INFO_INIT;
+  args.flags &= ~S_CTX_INFO_INIT;
+
+  pid = initSync(p, args.do_disconnect);
+  if (pid==0) {
+    doSyncStage0(p, args.do_disconnect);
+    
+    newctx            = Evc_new_s_context(args.ctxs[0],0,args.flags);
+    args.remove_caps &= (~args.add_caps);
+    setHostname(args.hostname);
+    setDomainname(args.domainname);
+
+    if (args.remove_caps!=0 || xflags!=0)
+      Evc_new_s_context (VC_SAMECTX,args.remove_caps,xflags);
+    tellContext(args.ctxs[0]==VC_DYNAMIC_XID ? newctx : args.ctxs[0]);
+
+    doSyncStage1(p, args.do_disconnect);
+    execvp (argv[optind],argv+optind);
+    doSyncStage2(p, args.do_disconnect);
+
+    PERROR_Q("chcontext: execvp", argv[optind]);
+    exit(255);
+  }
+
+  waitOnSync(pid, p, args.ctxs[0]!=VC_DYNAMIC_XID);
+  return EXIT_SUCCESS;
 }
 
+#ifdef ENSC_TESTSUITE
+#define FLAG_TEST(STR,EXP) \
+  {                       \
+    uint32_t   flag=0;    \
+    setFlags(STR, &flag);  \
+    assert(flag==(EXP));   \
+  }
+
+#define CAP_TEST(STR,EXP_ADD,EXP_DEL)          \
+  {                                            \
+    uint32_t   add=0,del=0;                    \
+    setCap(STR, &add, &del);                   \
+    assert(add==(EXP_ADD));                    \
+    assert(del==(EXP_DEL));                    \
+  }
+
+void
+test()
+{
+  FLAG_TEST("lock",       1);
+  FLAG_TEST("lock,sched", 3);
+
+  CAP_TEST("CHOWN",      1, 0);
+  CAP_TEST("CAP_CHOWN",  1, 0);
+  CAP_TEST("!CHOWN",     0, 1);
+  CAP_TEST("!CAP_CHOWN", 0, 1);
+}
+#endif
index 1d7783e..94437dc 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: showattr.c,v 1.1.4.1 2003/11/18 22:31:10 ensc Exp $
+// $Id: showattr.c,v 1.11 2005/03/24 12:44:17 ensc Exp $
 
 // Copyright (C) 2003 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
 // based on showattr.cc by Jacques Gelinas
 #ifdef HAVE_CONFIG_H
 #  include <config.h>
 #endif
-#include "compat.h"
 
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
+#include "fstool.h"
+#include "util.h"
 
-#include "ext2fs.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>
+#include <ctype.h>
 
-// Patch to help compile this utility on unpatched kernel source
-#ifndef EXT2_IUNLINK_FL
-/* Set both bits for backward compatibility */
-#define EXT2_IUNLINK_FL 0x08008000
+struct option const
+CMDLINE_OPTIONS[] = {
+  { "help",     no_argument,  0, CMD_HELP },
+  { "version",  no_argument,  0, CMD_VERSION },
+#ifdef VC_ENABLE_API_LEGACY
+  { "legacy",    no_argument, 0, CMD_LEGACY },
 #endif
+  { 0,0,0,0 }
+};
 
-#ifndef EXT2_BARRIER_FL
-#define EXT2_BARRIER_FL 0x04000000
-#endif
+char const             CMDLINE_OPTIONS_SHORT[] = "Radx";
 
-/*
-       Get the extended attributes of a file
-*/
-static int getext2flags (const char *fname, long *flags)
+void
+showHelp(int fd, char const *cmd, int res)
 {
-       int ret = -1;
-       int fd = open (fname,O_RDONLY);
-       if (fd == -1){
-               fprintf (stderr,"Can't open file %s (%s)\n",fname,strerror(errno));
-       }else{
-               *flags = 0;
-               ret = ioctl (fd,EXT2_IOC_GETFLAGS,flags);
-               close (fd);
-               if (ret == -1){
-                       fprintf (stderr,"Can't get ext2 flags on file %s (%s)\n"
-                               ,fname,strerror(errno));
-               }
-       }
-       return ret;
+  WRITE_MSG(fd, "Usage:  ");
+  WRITE_STR(fd, cmd);
+  WRITE_MSG(fd,
+           " [-Radx] [--] <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 listing\n"
+           "            their content\n"
+           "   -x  ...  do not cross filesystems\n\n"
+           "Please report bugs to " PACKAGE_BUGREPORT "\n");
+  exit(res);
 }
 
-/*
-       Set the extended attributes of a file
-*/
-static int setext2flags (const char *fname, long flags)
+void
+showVersion()
 {
-       int ret = -1;
-       int fd = open (fname,O_RDONLY);
-       if (fd == -1){
-               fprintf (stderr,"Can't open file %s (%s)\n",fname,strerror(errno));
-       }else{
-               ret = ioctl (fd,EXT2_IOC_SETFLAGS,&flags);
-               close (fd);
-               if (ret == -1){
-                       fprintf (stderr,"Can't set ext2 flags on file %s (%s)\n"
-                               ,fname,strerror(errno));
-               }
-       }
-       return ret;
+  WRITE_MSG(1,
+           "showattr " VERSION " -- shows 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
+fixupParams(struct Arguments UNUSED * args, int UNUSED argc)
+{
+}
 
-int main (int argc, char *argv[])
+static bool
+getFlags(char const *name, uint32_t *flags, uint32_t *mask)
 {
-       int ret = -1;
-       if (argc <= 1){
-               fprintf (stderr
-                       ,"showattr file ...\n"
-                        "\n"
-                        "Presents extended file attribute.\n"
-                        "\n"
-                        "setattr --immutable --immulink file ...\n"
-                        "\n"
-                        "Sets the extended file attributes.\n"
-                        "\n"
-                        "These utilities exist as an interim until lsattr and\n"
-                        "chattr are updated.\n"
-                       );
-       }else if (strstr(argv[0],"showattr")!=NULL){
-               int i;
-               for (i=1; i<argc; i++){
-                       long flags;
-                       ret = getext2flags (argv[i],&flags);
-                       if (ret == -1){
-                               break;
-                       }else{
-                               printf ("%s\t%08lx\n",argv[i],flags);
-                       }
-               }
-       }else if (strstr(argv[0],"setattr")!=NULL){
-               long flags, add_flags = 0, remove_flags = 0;
-               int  i;
-               ret = 0;
-               for (i=1; i<argc; i++){
-                       const char *arg = argv[i];
-                       if (strncmp(arg,"--",2)==0){
-                               if (strcmp(arg,"--immutable")==0){
-                                       add_flags |= EXT2_IMMUTABLE_FL;
-                               }else if (strcmp(arg,"--!immutable")==0 || strcmp(arg,"--~immutable")==0){
-                                       remove_flags |= EXT2_IMMUTABLE_FL;
-                               }else if (strcmp(arg,"--immulink")==0){
-                                       add_flags |= EXT2_IUNLINK_FL;
-                               }else if (strcmp(arg,"--!immulink")==0 || strcmp(arg,"--~immulink")==0){
-                                       remove_flags |= EXT2_IUNLINK_FL;
-                               }else if (strcmp(arg,"--barrier")==0){
-                                       add_flags |= EXT2_BARRIER_FL;
-                               }else if (strcmp(arg,"--!barrier")==0 || strcmp(arg,"--~barrier")==0){
-                                       remove_flags |= EXT2_BARRIER_FL;
-                               }else{
-                                       fprintf (stderr,"Invalid option %s\n",arg);
-                                       ret = -1;
-                                       break;
-                               }
-                       }else{
-                               ret = getext2flags (arg,&flags);
-                               if (ret == -1){
-                                       break;
-                               }
-                               flags |= add_flags;
-                               flags &= ~remove_flags;
-                               ret = setext2flags (arg,flags);
-                               if (ret == -1){
-                                       break;
-                               }
-                       }
-               }
-       }
-       return ret;
+  xid_t                xid;
+  *mask = ~0;
+  
+  if (vc_get_iattr(name, &xid, flags, mask)==-1) {
+    perror("vc_get_iattr()");
+    return false;
+  }
+
+  return true;
 }
 
+bool
+handleFile(char const *name, char const *display_name)
+{
+  bool                 res = true;
+  char                 buf[40];
+  char                 *ptr = buf;
+  uint32_t             flags;
+  uint32_t             mask;
+
+  memset(buf, ' ', sizeof buf);
+
+  if (getFlags(name, &flags, &mask)) {
+      //                                     1       1       0       0
+      //                              fedcba9876543210fedcba9876543210
+    static char const  MARKER[33] = ".......x.....iub.............hwa";
+    int                i;
+    uint32_t           used_flags = (VC_IATTR_XID|VC_IATTR_ADMIN|
+                                     VC_IATTR_WATCH|VC_IATTR_HIDE|
+                                     VC_IATTR_BARRIER|VC_IATTR_IUNLINK|
+                                     VC_IATTR_IMMUTABLE);
+
+    for (i=0; i<32; ++i) {
+      if (used_flags & 1) {
+       if (!   (mask  & 1) ) *ptr++ = '-';
+       else if (flags & 1)   *ptr++ = toupper(MARKER[31-i]);
+       else                  *ptr++ = MARKER[31-i];
+      }
+
+      used_flags >>= 1;
+      flags      >>= 1;
+      mask       >>= 1;
+    }
+  }      
+  else {
+    memcpy(buf, "ERR   ", 7);
+    res = false;
+  }
+
+  Vwrite(1, buf, 8);
+  Vwrite(1, display_name, strlen(display_name));
+  Vwrite(1, "\n", 1);
+
+  return res;
+}
index b6cfc59..f784a35 100644 (file)
--- a/src/vdu.c
+++ b/src/vdu.c
 
 #define _LARGEFILE64_SOURCE
 
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
 #include <stdlib.h>
 #include <stdio.h>
 #include <sys/stat.h>