From: Planet-Lab Support <support@planet-lab.org>
Date: Sat, 18 Jun 2005 06:08:51 +0000 (+0000)
Subject: This commit was manufactured by cvs2svn to create tag
X-Git-Tag: util-vserver-0_30-6_planetlab^0
X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=c8e46b7b46a3b1785acf92471aa021e351128e24;p=util-vserver.git

This commit was manufactured by cvs2svn to create tag
'util-vserver-0_30-6_planetlab'.
---

diff --git a/Makefile.am b/Makefile.am
index 437c818..1ef9cc9 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -83,6 +83,13 @@ else
 		ln -sf '$(top_srcdir)/lib/virtual.h' '$@'
 endif
 
+install-exec-hook:
+	cd $(DESTDIR)$(sbindir) && $(LN_S) vuseradd vadduser
+	cd $(DESTDIR)$(sbindir) && $(LN_S) vuserdel vdeluser
+
+install-data-hook:
+	cd $(DESTDIR)$(sysvdir) && $(LN_S) vservers vserver-init
+
 include $(top_srcdir)/lib/Makefile-files
 include $(top_srcdir)/src/Makefile-files
 include $(top_srcdir)/distrib/Makefile-files
diff --git a/Makefile.in b/Makefile.in
index 9500fae..44b4141 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.8.4 from Makefile.am.
+# Makefile.in generated by automake 1.8.3 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -35,7 +35,7 @@
 
 
 
-SOURCES = $(lib_libvserver_a_SOURCES) $(src_capchroot_SOURCES) $(src_chbind_SOURCES) $(src_chcontext_SOURCES) $(src_fakerunlevel_SOURCES) $(src_filetime_SOURCES) $(src_ifspec_SOURCES) $(src_listdevip_SOURCES) $(src_parserpmdump_SOURCES) $(src_readlink_SOURCES) $(src_rebootmgr_SOURCES) $(src_reducecap_SOURCES) $(src_showattr_SOURCES) $(src_showperm_SOURCES) $(src_vbuild_SOURCES) $(src_vcheck_SOURCES) $(src_vdu_SOURCES) $(src_vfiles_SOURCES) $(src_vkill_SOURCES) $(src_vlimit_SOURCES) $(src_vreboot_SOURCES) $(src_vserver_stat_SOURCES) $(src_vunify_SOURCES) $(tests_escaperoot_SOURCES) $(tests_forkbomb_SOURCES) $(tests_testipc_SOURCES) $(tests_testlimit_SOURCES) $(tests_testopenf_SOURCES)
+SOURCES = $(lib_libvserver_a_SOURCES) $(src_capchroot_SOURCES) $(src_chbind_SOURCES) $(src_chcontext_SOURCES) $(src_fakerunlevel_SOURCES) $(src_filetime_SOURCES) $(src_ifspec_SOURCES) $(src_listdevip_SOURCES) $(src_parserpmdump_SOURCES) $(src_readlink_SOURCES) $(src_rebootmgr_SOURCES) $(src_reducecap_SOURCES) $(src_showattr_SOURCES) $(src_showperm_SOURCES) $(src_vbuild_SOURCES) $(src_vcheck_SOURCES) $(src_vdlimit_SOURCES) $(src_vdu_SOURCES) $(src_vfiles_SOURCES) $(src_vkill_SOURCES) $(src_vreboot_SOURCES) $(src_vserver_stat_SOURCES) $(src_vsh_SOURCES) $(src_vunify_SOURCES) $(tests_escaperoot_SOURCES) $(tests_forkbomb_SOURCES) $(tests_testipc_SOURCES) $(tests_testlimit_SOURCES) $(tests_testopenf_SOURCES)
 
 srcdir = @srcdir@
 top_srcdir = @top_srcdir@
@@ -120,8 +120,8 @@ am__EXEEXT_2 = src/capchroot$(EXEEXT) src/fakerunlevel$(EXEEXT) \
 	src/vreboot$(EXEEXT) src/vunify$(EXEEXT)
 pkglibPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
 am__EXEEXT_3 = src/chbind$(EXEEXT) src/chcontext$(EXEEXT) \
-	src/rebootmgr$(EXEEXT) src/reducecap$(EXEEXT) \
-	src/vlimit$(EXEEXT) src/vdu$(EXEEXT) src/vfiles$(EXEEXT) \
+	src/rebootmgr$(EXEEXT) src/reducecap$(EXEEXT) src/vdu$(EXEEXT) \
+	src/vsh$(EXEEXT) src/vdlimit$(EXEEXT) src/vfiles$(EXEEXT) \
 	src/vkill$(EXEEXT) src/vserver-stat$(EXEEXT)
 sbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
 PROGRAMS = $(noinst_PROGRAMS) $(pkglib_PROGRAMS) $(sbin_PROGRAMS)
@@ -170,6 +170,9 @@ src_vbuild_LDADD = $(LDADD)
 am_src_vcheck_OBJECTS = src/vcheck.$(OBJEXT) src/vutil.$(OBJEXT)
 src_vcheck_OBJECTS = $(am_src_vcheck_OBJECTS)
 src_vcheck_LDADD = $(LDADD)
+am_src_vdlimit_OBJECTS = src/vdlimit.$(OBJEXT)
+src_vdlimit_OBJECTS = $(am_src_vdlimit_OBJECTS)
+src_vdlimit_DEPENDENCIES = lib/libvserver.a
 am_src_vdu_OBJECTS = src/vdu.$(OBJEXT)
 src_vdu_OBJECTS = $(am_src_vdu_OBJECTS)
 src_vdu_LDADD = $(LDADD)
@@ -179,15 +182,15 @@ src_vfiles_LDADD = $(LDADD)
 am_src_vkill_OBJECTS = src/src_vkill-vkill.$(OBJEXT)
 src_vkill_OBJECTS = $(am_src_vkill_OBJECTS)
 src_vkill_DEPENDENCIES = lib/libvserver.a
-am_src_vlimit_OBJECTS = src/vlimit.$(OBJEXT)
-src_vlimit_OBJECTS = $(am_src_vlimit_OBJECTS)
-src_vlimit_DEPENDENCIES = lib/libvserver.a
 am_src_vreboot_OBJECTS = src/vreboot.$(OBJEXT)
 src_vreboot_OBJECTS = $(am_src_vreboot_OBJECTS)
 src_vreboot_LDADD = $(LDADD)
 am_src_vserver_stat_OBJECTS = src/vserver-stat.$(OBJEXT)
 src_vserver_stat_OBJECTS = $(am_src_vserver_stat_OBJECTS)
 src_vserver_stat_DEPENDENCIES = lib/libvserver.a
+am_src_vsh_OBJECTS = src/vsh.$(OBJEXT)
+src_vsh_OBJECTS = $(am_src_vsh_OBJECTS)
+src_vsh_DEPENDENCIES = lib/libvserver.a
 am_src_vunify_OBJECTS = src/src_vunify-vunify.$(OBJEXT) \
 	src/src_vunify-vutil.$(OBJEXT)
 src_vunify_OBJECTS = $(am_src_vunify_OBJECTS)
@@ -239,9 +242,9 @@ am__depfiles_maybe = depfiles
 @AMDEP_TRUE@	src/$(DEPDIR)/src_vunify-vunify.Po \
 @AMDEP_TRUE@	src/$(DEPDIR)/src_vunify-vutil.Po \
 @AMDEP_TRUE@	src/$(DEPDIR)/vbuild.Po src/$(DEPDIR)/vcheck.Po \
-@AMDEP_TRUE@	src/$(DEPDIR)/vdu.Po src/$(DEPDIR)/vfiles.Po \
-@AMDEP_TRUE@	src/$(DEPDIR)/vlimit.Po src/$(DEPDIR)/vreboot.Po \
-@AMDEP_TRUE@	src/$(DEPDIR)/vserver-stat.Po \
+@AMDEP_TRUE@	src/$(DEPDIR)/vdlimit.Po src/$(DEPDIR)/vdu.Po \
+@AMDEP_TRUE@	src/$(DEPDIR)/vfiles.Po src/$(DEPDIR)/vreboot.Po \
+@AMDEP_TRUE@	src/$(DEPDIR)/vserver-stat.Po src/$(DEPDIR)/vsh.Po \
 @AMDEP_TRUE@	src/$(DEPDIR)/vutil.Po \
 @AMDEP_TRUE@	tests/$(DEPDIR)/escaperoot.Po \
 @AMDEP_TRUE@	tests/$(DEPDIR)/forkbomb.Po \
@@ -264,10 +267,11 @@ SOURCES = $(lib_libvserver_a_SOURCES) $(src_capchroot_SOURCES) \
 	$(src_parserpmdump_SOURCES) $(src_readlink_SOURCES) \
 	$(src_rebootmgr_SOURCES) $(src_reducecap_SOURCES) \
 	$(src_showattr_SOURCES) $(src_showperm_SOURCES) \
-	$(src_vbuild_SOURCES) $(src_vcheck_SOURCES) $(src_vdu_SOURCES) \
+	$(src_vbuild_SOURCES) $(src_vcheck_SOURCES) \
+	$(src_vdlimit_SOURCES) $(src_vdu_SOURCES) \
 	$(src_vfiles_SOURCES) $(src_vkill_SOURCES) \
-	$(src_vlimit_SOURCES) $(src_vreboot_SOURCES) \
-	$(src_vserver_stat_SOURCES) $(src_vunify_SOURCES) \
+	$(src_vreboot_SOURCES) $(src_vserver_stat_SOURCES) \
+	$(src_vsh_SOURCES) $(src_vunify_SOURCES) \
 	$(tests_escaperoot_SOURCES) $(tests_forkbomb_SOURCES) \
 	$(tests_testipc_SOURCES) $(tests_testlimit_SOURCES) \
 	$(tests_testopenf_SOURCES)
@@ -278,10 +282,11 @@ DIST_SOURCES = $(lib_libvserver_a_SOURCES) $(src_capchroot_SOURCES) \
 	$(src_parserpmdump_SOURCES) $(src_readlink_SOURCES) \
 	$(src_rebootmgr_SOURCES) $(src_reducecap_SOURCES) \
 	$(src_showattr_SOURCES) $(src_showperm_SOURCES) \
-	$(src_vbuild_SOURCES) $(src_vcheck_SOURCES) $(src_vdu_SOURCES) \
+	$(src_vbuild_SOURCES) $(src_vcheck_SOURCES) \
+	$(src_vdlimit_SOURCES) $(src_vdu_SOURCES) \
 	$(src_vfiles_SOURCES) $(src_vkill_SOURCES) \
-	$(src_vlimit_SOURCES) $(src_vreboot_SOURCES) \
-	$(src_vserver_stat_SOURCES) $(src_vunify_SOURCES) \
+	$(src_vreboot_SOURCES) $(src_vserver_stat_SOURCES) \
+	$(src_vsh_SOURCES) $(src_vunify_SOURCES) \
 	$(tests_escaperoot_SOURCES) $(tests_forkbomb_SOURCES) \
 	$(tests_testipc_SOURCES) $(tests_testlimit_SOURCES) \
 	$(tests_testopenf_SOURCES)
@@ -483,12 +488,14 @@ src_sbin_PRGS = src/chbind \
 			   src/chcontext \
 			   src/rebootmgr \
 			   src/reducecap \
-			   src/vlimit \
 			   src/vdu \
+			   src/vsh \
+			   src/vdlimit \
 			   src/vfiles \
 			   src/vkill \
 			   src/vserver-stat
 
+src_sbin_PRGS_broken = src/vlimit
 src_GENFILES = src/setattr
 src_capchroot_SOURCES = src/capchroot.c
 src_capchroot_LDADD = lib/libvserver.a
@@ -511,6 +518,10 @@ src_vlimit_LDADD = lib/libvserver.a
 src_vkill_SOURCES = src/vkill.c
 src_vkill_LDADD = lib/libvserver.a
 src_vkill_CPPFLAGS = $(AM_CPPFLAGS) -DLEGACYDIR=\"$(legacydir)\"
+src_vsh_SOURCES = src/vsh.c
+src_vsh_LDADD = lib/libvserver.a
+src_vdlimit_SOURCES = src/vdlimit.c
+src_vdlimit_LDADD = lib/libvserver.a
 src_showattr_SOURCES = src/showattr.c
 src_showperm_SOURCES = src/showperm.c
 src_vbuild_SOURCES = src/vbuild.cc src/vutil.cc
@@ -530,6 +541,7 @@ distrib_SCRPTS = distrib/install-mdk8.2 \
 			  distrib/install-rh8.0 \
 			  distrib/install-rh9.0 \
 			  distrib/install-fc1 \
+			  distrib/install-fc2 \
 			  distrib/sample.sh
 
 distrib_DAT = distrib/mdk8.2-minimum \
@@ -569,6 +581,9 @@ scripts_src_PRGS = scripts/vpstree \
 			   scripts/vrpm \
 			   scripts/vserver \
 			   scripts/vserver-copy \
+			   scripts/vcached \
+			   scripts/vuseradd \
+			   scripts/vuserdel \
 			   scripts/vtop
 
 scripts_gen_PRGS = scripts/vps
@@ -606,6 +621,7 @@ sysv_XTRAS = sysv/rebootmgr.subst \
 			   sysv/v_smb.subst \
 			   sysv/v_sshd.subst \
 			   sysv/v_xinetd.subst \
+			   sysv/vcached.subst \
 			   sysv/vservers.subst
 
 sysv_GENSCRPTS = sysv/rebootmgr \
@@ -617,10 +633,11 @@ sysv_GENSCRPTS = sysv/rebootmgr \
 			   sysv/v_smb \
 			   sysv/v_sshd \
 			   sysv/v_xinetd \
+			   sysv/vcached \
 			   sysv/vservers
 
 sysv_SCRPTS = $(sysv_GENSCRPTS)
-sysv_CFG = sysv/vservers.conf
+sysv_CFG = sysv/vservers.conf sysv/vcached.conf
 linuxconf_gen_SCRPTS = linuxconf/newvserver
 linuxconf_src_DATMAN = linuxconf/newvserver.8
 linuxconf_cfg_src_DTA = linuxconf/newvserver.defaults
@@ -876,6 +893,11 @@ src/vcheck.$(OBJEXT): src/$(am__dirstamp) \
 src/vcheck$(EXEEXT): $(src_vcheck_OBJECTS) $(src_vcheck_DEPENDENCIES) src/$(am__dirstamp)
 	@rm -f src/vcheck$(EXEEXT)
 	$(CXXLINK) $(src_vcheck_LDFLAGS) $(src_vcheck_OBJECTS) $(src_vcheck_LDADD) $(LIBS)
+src/vdlimit.$(OBJEXT): src/$(am__dirstamp) \
+	src/$(DEPDIR)/$(am__dirstamp)
+src/vdlimit$(EXEEXT): $(src_vdlimit_OBJECTS) $(src_vdlimit_DEPENDENCIES) src/$(am__dirstamp)
+	@rm -f src/vdlimit$(EXEEXT)
+	$(LINK) $(src_vdlimit_LDFLAGS) $(src_vdlimit_OBJECTS) $(src_vdlimit_LDADD) $(LIBS)
 src/vdu.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
 src/vdu$(EXEEXT): $(src_vdu_OBJECTS) $(src_vdu_DEPENDENCIES) src/$(am__dirstamp)
 	@rm -f src/vdu$(EXEEXT)
@@ -890,11 +912,6 @@ src/src_vkill-vkill.$(OBJEXT): src/$(am__dirstamp) \
 src/vkill$(EXEEXT): $(src_vkill_OBJECTS) $(src_vkill_DEPENDENCIES) src/$(am__dirstamp)
 	@rm -f src/vkill$(EXEEXT)
 	$(LINK) $(src_vkill_LDFLAGS) $(src_vkill_OBJECTS) $(src_vkill_LDADD) $(LIBS)
-src/vlimit.$(OBJEXT): src/$(am__dirstamp) \
-	src/$(DEPDIR)/$(am__dirstamp)
-src/vlimit$(EXEEXT): $(src_vlimit_OBJECTS) $(src_vlimit_DEPENDENCIES) src/$(am__dirstamp)
-	@rm -f src/vlimit$(EXEEXT)
-	$(LINK) $(src_vlimit_LDFLAGS) $(src_vlimit_OBJECTS) $(src_vlimit_LDADD) $(LIBS)
 src/vreboot.$(OBJEXT): src/$(am__dirstamp) \
 	src/$(DEPDIR)/$(am__dirstamp)
 src/vreboot$(EXEEXT): $(src_vreboot_OBJECTS) $(src_vreboot_DEPENDENCIES) src/$(am__dirstamp)
@@ -905,6 +922,10 @@ src/vserver-stat.$(OBJEXT): src/$(am__dirstamp) \
 src/vserver-stat$(EXEEXT): $(src_vserver_stat_OBJECTS) $(src_vserver_stat_DEPENDENCIES) src/$(am__dirstamp)
 	@rm -f src/vserver-stat$(EXEEXT)
 	$(LINK) $(src_vserver_stat_LDFLAGS) $(src_vserver_stat_OBJECTS) $(src_vserver_stat_LDADD) $(LIBS)
+src/vsh.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
+src/vsh$(EXEEXT): $(src_vsh_OBJECTS) $(src_vsh_DEPENDENCIES) src/$(am__dirstamp)
+	@rm -f src/vsh$(EXEEXT)
+	$(LINK) $(src_vsh_LDFLAGS) $(src_vsh_OBJECTS) $(src_vsh_LDADD) $(LIBS)
 src/src_vunify-vunify.$(OBJEXT): src/$(am__dirstamp) \
 	src/$(DEPDIR)/$(am__dirstamp)
 src/src_vunify-vutil.$(OBJEXT): src/$(am__dirstamp) \
@@ -1047,11 +1068,12 @@ mostlyclean-compile:
 	-rm -f src/src_vunify-vutil.$(OBJEXT)
 	-rm -f src/vbuild.$(OBJEXT)
 	-rm -f src/vcheck.$(OBJEXT)
+	-rm -f src/vdlimit.$(OBJEXT)
 	-rm -f src/vdu.$(OBJEXT)
 	-rm -f src/vfiles.$(OBJEXT)
-	-rm -f src/vlimit.$(OBJEXT)
 	-rm -f src/vreboot.$(OBJEXT)
 	-rm -f src/vserver-stat.$(OBJEXT)
+	-rm -f src/vsh.$(OBJEXT)
 	-rm -f src/vutil.$(OBJEXT)
 	-rm -f tests/escaperoot.$(OBJEXT)
 	-rm -f tests/forkbomb.$(OBJEXT)
@@ -1087,11 +1109,12 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/src_vunify-vutil.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/vbuild.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/vcheck.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/vdlimit.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/vdu.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/vfiles.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/vlimit.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/vreboot.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/vserver-stat.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/vsh.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/vutil.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/escaperoot.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/forkbomb.Po@am__quote@
@@ -1435,6 +1458,22 @@ src/showperm.obj: src/showperm.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/showperm.obj `if test -f 'src/showperm.c'; then $(CYGPATH_W) 'src/showperm.c'; else $(CYGPATH_W) '$(srcdir)/src/showperm.c'; fi`
 
+src/vdlimit.o: src/vdlimit.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/vdlimit.o -MD -MP -MF "src/$(DEPDIR)/vdlimit.Tpo" -c -o src/vdlimit.o `test -f 'src/vdlimit.c' || echo '$(srcdir)/'`src/vdlimit.c; \
+@am__fastdepCC_TRUE@	then mv -f "src/$(DEPDIR)/vdlimit.Tpo" "src/$(DEPDIR)/vdlimit.Po"; else rm -f "src/$(DEPDIR)/vdlimit.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='src/vdlimit.c' object='src/vdlimit.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	depfile='src/$(DEPDIR)/vdlimit.Po' tmpdepfile='src/$(DEPDIR)/vdlimit.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/vdlimit.o `test -f 'src/vdlimit.c' || echo '$(srcdir)/'`src/vdlimit.c
+
+src/vdlimit.obj: src/vdlimit.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/vdlimit.obj -MD -MP -MF "src/$(DEPDIR)/vdlimit.Tpo" -c -o src/vdlimit.obj `if test -f 'src/vdlimit.c'; then $(CYGPATH_W) 'src/vdlimit.c'; else $(CYGPATH_W) '$(srcdir)/src/vdlimit.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "src/$(DEPDIR)/vdlimit.Tpo" "src/$(DEPDIR)/vdlimit.Po"; else rm -f "src/$(DEPDIR)/vdlimit.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='src/vdlimit.c' object='src/vdlimit.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	depfile='src/$(DEPDIR)/vdlimit.Po' tmpdepfile='src/$(DEPDIR)/vdlimit.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/vdlimit.obj `if test -f 'src/vdlimit.c'; then $(CYGPATH_W) 'src/vdlimit.c'; else $(CYGPATH_W) '$(srcdir)/src/vdlimit.c'; fi`
+
 src/vdu.o: src/vdu.c
 @am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/vdu.o -MD -MP -MF "src/$(DEPDIR)/vdu.Tpo" -c -o src/vdu.o `test -f 'src/vdu.c' || echo '$(srcdir)/'`src/vdu.c; \
 @am__fastdepCC_TRUE@	then mv -f "src/$(DEPDIR)/vdu.Tpo" "src/$(DEPDIR)/vdu.Po"; else rm -f "src/$(DEPDIR)/vdu.Tpo"; exit 1; fi
@@ -1467,22 +1506,6 @@ src/src_vkill-vkill.obj: src/vkill.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_vkill_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/src_vkill-vkill.obj `if test -f 'src/vkill.c'; then $(CYGPATH_W) 'src/vkill.c'; else $(CYGPATH_W) '$(srcdir)/src/vkill.c'; fi`
 
-src/vlimit.o: src/vlimit.c
-@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/vlimit.o -MD -MP -MF "src/$(DEPDIR)/vlimit.Tpo" -c -o src/vlimit.o `test -f 'src/vlimit.c' || echo '$(srcdir)/'`src/vlimit.c; \
-@am__fastdepCC_TRUE@	then mv -f "src/$(DEPDIR)/vlimit.Tpo" "src/$(DEPDIR)/vlimit.Po"; else rm -f "src/$(DEPDIR)/vlimit.Tpo"; exit 1; fi
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='src/vlimit.c' object='src/vlimit.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	depfile='src/$(DEPDIR)/vlimit.Po' tmpdepfile='src/$(DEPDIR)/vlimit.TPo' @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/vlimit.o `test -f 'src/vlimit.c' || echo '$(srcdir)/'`src/vlimit.c
-
-src/vlimit.obj: src/vlimit.c
-@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/vlimit.obj -MD -MP -MF "src/$(DEPDIR)/vlimit.Tpo" -c -o src/vlimit.obj `if test -f 'src/vlimit.c'; then $(CYGPATH_W) 'src/vlimit.c'; else $(CYGPATH_W) '$(srcdir)/src/vlimit.c'; fi`; \
-@am__fastdepCC_TRUE@	then mv -f "src/$(DEPDIR)/vlimit.Tpo" "src/$(DEPDIR)/vlimit.Po"; else rm -f "src/$(DEPDIR)/vlimit.Tpo"; exit 1; fi
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='src/vlimit.c' object='src/vlimit.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	depfile='src/$(DEPDIR)/vlimit.Po' tmpdepfile='src/$(DEPDIR)/vlimit.TPo' @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/vlimit.obj `if test -f 'src/vlimit.c'; then $(CYGPATH_W) 'src/vlimit.c'; else $(CYGPATH_W) '$(srcdir)/src/vlimit.c'; fi`
-
 src/vreboot.o: src/vreboot.c
 @am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/vreboot.o -MD -MP -MF "src/$(DEPDIR)/vreboot.Tpo" -c -o src/vreboot.o `test -f 'src/vreboot.c' || echo '$(srcdir)/'`src/vreboot.c; \
 @am__fastdepCC_TRUE@	then mv -f "src/$(DEPDIR)/vreboot.Tpo" "src/$(DEPDIR)/vreboot.Po"; else rm -f "src/$(DEPDIR)/vreboot.Tpo"; exit 1; fi
@@ -1515,6 +1538,22 @@ src/vserver-stat.obj: src/vserver-stat.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/vserver-stat.obj `if test -f 'src/vserver-stat.c'; then $(CYGPATH_W) 'src/vserver-stat.c'; else $(CYGPATH_W) '$(srcdir)/src/vserver-stat.c'; fi`
 
+src/vsh.o: src/vsh.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/vsh.o -MD -MP -MF "src/$(DEPDIR)/vsh.Tpo" -c -o src/vsh.o `test -f 'src/vsh.c' || echo '$(srcdir)/'`src/vsh.c; \
+@am__fastdepCC_TRUE@	then mv -f "src/$(DEPDIR)/vsh.Tpo" "src/$(DEPDIR)/vsh.Po"; else rm -f "src/$(DEPDIR)/vsh.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='src/vsh.c' object='src/vsh.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	depfile='src/$(DEPDIR)/vsh.Po' tmpdepfile='src/$(DEPDIR)/vsh.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/vsh.o `test -f 'src/vsh.c' || echo '$(srcdir)/'`src/vsh.c
+
+src/vsh.obj: src/vsh.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/vsh.obj -MD -MP -MF "src/$(DEPDIR)/vsh.Tpo" -c -o src/vsh.obj `if test -f 'src/vsh.c'; then $(CYGPATH_W) 'src/vsh.c'; else $(CYGPATH_W) '$(srcdir)/src/vsh.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "src/$(DEPDIR)/vsh.Tpo" "src/$(DEPDIR)/vsh.Po"; else rm -f "src/$(DEPDIR)/vsh.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='src/vsh.c' object='src/vsh.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	depfile='src/$(DEPDIR)/vsh.Po' tmpdepfile='src/$(DEPDIR)/vsh.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/vsh.obj `if test -f 'src/vsh.c'; then $(CYGPATH_W) 'src/vsh.c'; else $(CYGPATH_W) '$(srcdir)/src/vsh.c'; fi`
+
 .cc.o:
 @am__fastdepCXX_TRUE@	if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
 @am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@@ -1858,11 +1897,9 @@ TAGS:  $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
 	  done | \
 	  $(AWK) '    { files[$$0] = 1; } \
 	       END { for (i in files) print i; }'`; \
-	if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
-	  test -z "$$unique" && unique=$$empty_fix; \
-	  $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
-	    $$tags $$unique; \
-	fi
+	test -z "$(ETAGS_ARGS)$$tags$$unique" \
+	  || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	     $$tags $$unique
 ctags: CTAGS
 CTAGS:  $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
 		$(TAGS_FILES) $(LISP)
@@ -1958,7 +1995,7 @@ distcheck: dist
 	*.tar.Z*) \
 	  uncompress -c $(distdir).tar.Z | $(AMTAR) xf - ;;\
 	*.shar.gz*) \
-	  GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\
+	  GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | unshar ;;\
 	*.zip*) \
 	  unzip $(distdir).zip ;;\
 	esac
@@ -2080,10 +2117,14 @@ info-am:
 install-data-am: install-includeHEADERS install-legacySCRIPTS \
 	install-man install-scriptscfgDATA install-sysvSCRIPTS \
 	install-vservercfgDATA
+	@$(NORMAL_INSTALL)
+	$(MAKE) $(AM_MAKEFLAGS) install-data-hook
 
 install-exec-am: install-libLIBRARIES install-pkglibDATA \
 	install-pkglibPROGRAMS install-pkglibSCRIPTS \
 	install-sbinPROGRAMS install-sbinSCRIPTS install-sysconfDATA
+	@$(NORMAL_INSTALL)
+	$(MAKE) $(AM_MAKEFLAGS) install-exec-hook
 
 install-info: install-info-am
 
@@ -2160,6 +2201,13 @@ linuxvirtual.h:
 @ENSC_ENABLE_INTERNAL_HEADERS_FALSE@		ln -sf '$(kernelincludedir)/linux/virtual.h' '$@' && test -e '$@' || \
 @ENSC_ENABLE_INTERNAL_HEADERS_FALSE@		ln -sf '$(top_srcdir)/lib/virtual.h' '$@'
 
+install-exec-hook:
+	cd $(DESTDIR)$(sbindir) && $(LN_S) vuseradd vadduser
+	cd $(DESTDIR)$(sbindir) && $(LN_S) vuserdel vdeluser
+
+install-data-hook:
+	cd $(DESTDIR)$(sysvdir) && $(LN_S) vservers vserver-init
+
 #install-data-hook:		$(DESTDIR)$(pkglibdir)/setattr
 
 #$(DESTDIR)$(pkglibdir)/setattr:
diff --git a/aclocal.m4 b/aclocal.m4
index c34e705..928b11c 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -1,4 +1,4 @@
-# generated automatically by aclocal 1.8.4 -*- Autoconf -*-
+# generated automatically by aclocal 1.8.3 -*- Autoconf -*-
 
 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
 # Free Software Foundation, Inc.
@@ -5965,7 +5965,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.8"])
 # Call AM_AUTOMAKE_VERSION so it can be traced.
 # This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
 AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-	 [AM_AUTOMAKE_VERSION([1.8.4])])
+	 [AM_AUTOMAKE_VERSION([1.8.3])])
 
 # AM_AUX_DIR_EXPAND
 
@@ -6191,14 +6191,9 @@ AC_CACHE_CHECK([dependency style of $depcc],
        grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
        ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
       # icc doesn't choke on unknown options, it will just issue warnings
-      # or remarks (even with -Werror).  So we grep stderr for any message
-      # that says an option was ignored or not supported.
-      # When given -MP, icc 7.0 and 7.1 complain thusly:
-      #   icc: Command line warning: ignoring option '-M'; no argument required
-      # The diagnosis changed in icc 8.0:
-      #   icc: Command line remark: option '-MP' not supported
-      if (grep 'ignoring option' conftest.err ||
-          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+      # (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored.
+      if grep 'ignoring option' conftest.err >/dev/null 2>&1; then :; else
         am_cv_$1_dependencies_compiler_type=$depmode
         break
       fi
diff --git a/configure b/configure
index eb2a46c..1177303 100755
--- a/configure
+++ b/configure
@@ -2491,14 +2491,9 @@ else
        grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
        ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
       # icc doesn't choke on unknown options, it will just issue warnings
-      # or remarks (even with -Werror).  So we grep stderr for any message
-      # that says an option was ignored or not supported.
-      # When given -MP, icc 7.0 and 7.1 complain thusly:
-      #   icc: Command line warning: ignoring option '-M'; no argument required
-      # The diagnosis changed in icc 8.0:
-      #   icc: Command line remark: option '-MP' not supported
-      if (grep 'ignoring option' conftest.err ||
-          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+      # (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored.
+      if grep 'ignoring option' conftest.err >/dev/null 2>&1; then :; else
         am_cv_CXX_dependencies_compiler_type=$depmode
         break
       fi
@@ -3329,14 +3324,9 @@ else
        grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
        ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
       # icc doesn't choke on unknown options, it will just issue warnings
-      # or remarks (even with -Werror).  So we grep stderr for any message
-      # that says an option was ignored or not supported.
-      # When given -MP, icc 7.0 and 7.1 complain thusly:
-      #   icc: Command line warning: ignoring option '-M'; no argument required
-      # The diagnosis changed in icc 8.0:
-      #   icc: Command line remark: option '-MP' not supported
-      if (grep 'ignoring option' conftest.err ||
-          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+      # (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored.
+      if grep 'ignoring option' conftest.err >/dev/null 2>&1; then :; else
         am_cv_CC_dependencies_compiler_type=$depmode
         break
       fi
diff --git a/distrib/Makefile-files b/distrib/Makefile-files
index a0e22cc..b870522 100644
--- a/distrib/Makefile-files
+++ b/distrib/Makefile-files
@@ -24,6 +24,7 @@ distrib_SCRPTS		= distrib/install-mdk8.2 \
 			  distrib/install-rh8.0 \
 			  distrib/install-rh9.0 \
 			  distrib/install-fc1 \
+			  distrib/install-fc2 \
 			  distrib/sample.sh
 
 distrib_DAT		= distrib/mdk8.2-minimum \
diff --git a/distrib/install-fc2 b/distrib/install-fc2
new file mode 100644
index 0000000..bf8f76b
--- /dev/null
+++ b/distrib/install-fc2
@@ -0,0 +1,50 @@
+#!/bin/sh
+
+# Copyright (C) 2003 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+# based on distrib/install-rh9.0 by Jacques Gelinas
+#  
+# 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; either version 2, or (at your option)
+# any later version.
+#  
+# 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.
+
+# This script creates a vserver from RedHat 9.0 CD. Only
+# the first CD is used and must be mounted in /mnt/cdrom.
+# Specify the name of the vserver
+# "install-rh9.0 test" will create /vservers/test
+
+: ${UTIL_VSERVER_VARS:=/usr/lib/util-vserver/util-vserver-vars}
+test -e "$UTIL_VSERVER_VARS" || {
+    echo "Can not find util-vserver installation; aborting..."
+    exit 1
+}
+. "$UTIL_VSERVER_VARS"
+
+USR_LIB_VSERVER=$PKGLIBDIR
+
+if [ $# -lt 1 ] ; then
+	echo $0 vserver-id [ group ]
+elif [ -d $VROOTDIR/$1/var/lib/rpm ] ; then
+	echo $VROOTDIR/$1 already exist
+else
+	VROOT=$VROOTDIR/$1
+	$USR_LIB_VSERVER/install-pre.sh $1
+	mkdir -p $VROOT/proc
+	mount -t proc none $VROOT/proc
+	mount -t devpts none $VROOT/dev/pts
+	mkdir -p $VROOT/var/lib/rpm
+	rpm --root $VROOT --initdb
+	yum --installroot="$VROOT" -y groupinstall "$2"
+	umount $VROOT/proc
+	umount $VROOT/dev/pts
+	$USR_LIB_VSERVER/install-post.sh $1
+fi
diff --git a/distrib/sample.conf b/distrib/sample.conf
index b56d9a3..9eb0dbc 100644
--- a/distrib/sample.conf
+++ b/distrib/sample.conf
@@ -2,23 +2,12 @@
 # The default is to allocate a free context on the fly
 # In general you don't need to force a context
 #S_CONTEXT=
-# Select the IP number assigned to the virtual server
-# This IP must be one IP of the server, either an interface
-# or an IP alias
-IPROOT=1.2.3.4
-# The netmask and broadcast are computed by default from IPROOTDEV
-#IPROOTMASK=
-#IPROOTBCAST=
-# You can define on which device the IP alias will be done
-# The IP alias will be set when the server is started and unset
-# when the server is stopped
-IPROOTDEV=eth0
 # Uncomment the onboot line if you want to enable this
 # virtual server at boot time
 #ONBOOT=yes
 # You can set a different host name for the vserver
 # If empty, the host name of the main server is used
-S_HOSTNAME=somename.somedomain.com
+S_HOSTNAME=
 # You can set a different NIS domain for the vserver
 # If empty, the current on is kept
 # Set it to "none" to have no NIS domain set
diff --git a/doc/FAQ.txt b/doc/FAQ.txt
deleted file mode 100644
index fe4bd67..0000000
--- a/doc/FAQ.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-
-                               Object not found!
-
-          The  requested URL was not found on this server. If you entered
-          the URL manually please check your spelling and try again.
-
-          If  you  think  this  is  a  server  error,  please contact the
-          [1]webmaster
-
-Error 404
-
-
-    [2]remtk
-    ven 18 jui 2003 11:41:32 EDT
-    Apache/2.0.40 (Red Hat Linux)
-
-Références
-
-   1. mailto:root@localhost
-   2. http://remtk/
diff --git a/doc/changelog.txt b/doc/changelog.txt
deleted file mode 100644
index fe4bd67..0000000
--- a/doc/changelog.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-
-                               Object not found!
-
-          The  requested URL was not found on this server. If you entered
-          the URL manually please check your spelling and try again.
-
-          If  you  think  this  is  a  server  error,  please contact the
-          [1]webmaster
-
-Error 404
-
-
-    [2]remtk
-    ven 18 jui 2003 11:41:32 EDT
-    Apache/2.0.40 (Red Hat Linux)
-
-Références
-
-   1. mailto:root@localhost
-   2. http://remtk/
diff --git a/lib/syscall_setsched-v13.hc b/lib/syscall_setsched-v13.hc
deleted file mode 100644
index 02284e0..0000000
--- a/lib/syscall_setsched-v13.hc
+++ /dev/null
@@ -1,70 +0,0 @@
-// $Id: syscall_setsched-v13.hc,v 1.4 2004/10/19 21:04:23 ensc Exp $    --*- 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 "sched_cmd.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)
-{
-#warning vc_set_sched_v13() uses an obsolete interface; remove it in the final version
-  struct vcmd_set_sched_v2	k_data;
-
-  
-  k_data.cpu_mask    = 0;
-  k_data.fill_rate   = VCGET(VC_VXSM_FILL_RATE,  data->fill_rate);
-  k_data.interval    = VCGET(VC_VXSM_INTERVAL,   data->interval);
-  k_data.tokens      = VCGET(VC_VXSM_TOKENS,     data->tokens);
-  k_data.tokens_min  = VCGET(VC_VXSM_TOKENS_MIN, data->tokens_min);
-  k_data.tokens_max  = VCGET(VC_VXSM_TOKENS_MAX, data->tokens_max);
-
-  return vserver(VCMD_set_sched_v2, CTX_USER2KERNEL(xid), &k_data);
-}
-
-#define X(ATTR)		ENSC_SAME_STRUCT_IDX(k_data, *data, ATTR)
-
-static inline ALWAYSINLINE int
-vc_set_sched_v13b(xid_t xid, struct vc_set_sched const *data)
-{
-  struct vcmd_set_sched_v3	k_data;
-
-    // This expression will be evaluated at compile-time
-  if (sizeof(struct vcmd_set_sched_v3)==sizeof(struct vc_set_sched) &&
-      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));
-  else {
-    k_data.set_mask      = data->set_mask;
-    k_data.fill_rate     = data->fill_rate;
-    k_data.interval      = data->interval;
-    k_data.tokens        = data->tokens;
-    k_data.tokens_min    = data->tokens_min;
-    k_data.tokens_max	 = data->tokens_max;
-    k_data.priority_bias = data->priority_bias;
-
-    return vserver(VCMD_set_sched, CTX_USER2KERNEL(xid), &k_data);
-  }
-}
diff --git a/lib/syscall_setsched.c b/lib/syscall_setsched.c
deleted file mode 100644
index 5884fc0..0000000
--- a/lib/syscall_setsched.c
+++ /dev/null
@@ -1,42 +0,0 @@
-// $Id: syscall_setsched.c,v 1.2 2004/09/22 20:45:37 ensc Exp $    --*- 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 "compat.h"
-
-#include "vserver.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
-
-int
-vc_set_sched(xid_t xid, struct vc_set_sched const *data)
-{
-  CALL_VC(CALL_VC_V13B  (vc_set_sched,xid,data),
-	  CALL_VC_V13OBS(vc_set_sched,xid,data));
-}
diff --git a/lib/virtual.h b/lib/virtual.h
index f55e6dd..f12b3d7 100644
--- a/lib/virtual.h
+++ b/lib/virtual.h
@@ -47,6 +47,8 @@
 
 #define VC_CAT_PROCTRL		12
 
+#define VC_CAT_DLIMIT		36
+
 #define VC_CAT_RLIMIT		60
 
 #define VC_CAT_SYSTEST		61
diff --git a/man/vsh.8 b/man/vsh.8
new file mode 100644
index 0000000..85f914c
--- /dev/null
+++ b/man/vsh.8
@@ -0,0 +1,48 @@
+.de Sh \" Subsection
+.br
+.if t .Sp
+.ne 5
+.PP
+\fB\\$1\fR
+.PP
+..
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Ip \" List item
+.br
+.ie \\n(.$>=3 .ne \\$3
+.el .ne 3
+.IP "\\$1" \\$2
+..
+.TH "VSH" 8 "2004-07-29" "PlanetLab specific Vserver shell" "vsh"
+
+.SH NAME
+vsh \- Safely trampoline's a slice user from global vserver context to
+the correspondingly named local vserver context\&.
+
+.SH "SYNOPSIS"
+ 
+.PP
+\fBvsh\fR [COMMAND] \fR
+ 
+.TP
+[COMMAND]
+when specified, the command to run, otherwise vsh will just run the
+user's shell as a login shell
+
+.SH "SUMMARY"
+ 
+.PP
+vsh is used as the login shell for slice users in the global vserver's
+/etc/passwd\&. It is invoked either by sshd when a slice user logs on
+to a PlanetLab node or as root using the su command\&. When this
+occurs, vsh switches vserver context and sets the uid/gid of the slice
+user, as specified in the slice's vserver /etc/passwd\&.
+
+.PP
+vsh assumes that the same account (by name) used to ssh/su into the
+vserver also exists in the vserver specific /etc/passwd file\&.  This
+is the only reason that for now it is deemed to be PlanetLab
+specific\&.
diff --git a/scripts/Makefile-files b/scripts/Makefile-files
index cec9518..fccc81b 100644
--- a/scripts/Makefile-files
+++ b/scripts/Makefile-files
@@ -36,6 +36,9 @@ scripts_src_PRGS	=  scripts/vpstree \
 			   scripts/vrpm \
 			   scripts/vserver \
 			   scripts/vserver-copy \
+			   scripts/vcached \
+			   scripts/vuseradd \
+			   scripts/vuserdel \
 			   scripts/vtop
 scripts_gen_PRGS	=  scripts/vps
 
diff --git a/scripts/vcached b/scripts/vcached
new file mode 100755
index 0000000..bb0b212
--- /dev/null
+++ b/scripts/vcached
@@ -0,0 +1,95 @@
+#!/bin/bash
+#
+# vcached: VServer cache daemon
+#
+# Description: A daemon that periodically preallocates vservers and stores
+# them in a cache.  Preallocated vservers from the cache may be then used to 
+# instantiate real vservers. Requires that /var/run/vcached.pid does not
+# exist on startup. Should start/stop/restart from /etc/init.d.
+#
+# Based on work by:
+# 
+# Brent Chun - bnc@intel-research.net
+# Tristan Koo - tristan.koo@intel-research.net
+# William Wung - wungism@uclink.berkeley.edu
+#
+# Mark Huang <mlhuang@cs.princeton.edu>
+# Copyright (c) 2004  The Trustees of Princeton University (Trustees).
+#
+# $Id: vcached,v 1.6 2004/10/13 02:35:47 mlhuang Exp $
+#
+
+# get configuration
+. /etc/vcached.conf
+
+# parse options
+while getopts 'fdl:' OPT ; do
+    case "$OPT" in
+        f) foreground=1 ;;
+        d) debug=1 ;;
+	l) exec 1>>$OPTARG ; exec 2>>$OPTARG ;;
+    esac
+done
+
+# check if we are already running
+if [ -f $pidfile ] ; then
+    echo "vcached(`cat $pidfile`) already running"
+    exit 1
+fi
+
+# daemonize
+if [ $foreground -eq 0 ] ; then
+    nohup setsid nice -n $nice -- $0 $* -f -l $logfile >/dev/null 2>&1 </dev/null &
+    exit 0
+fi
+
+# record PID
+trap "rm -f $pidfile ; exit 255" EXIT
+trap "exec 1>>$logfile ; exec 2>>$logfile" HUP
+echo $$ > $pidfile
+
+: ${UTIL_VSERVER_VARS:=$(dirname $0)/util-vserver-vars}
+test -e "$UTIL_VSERVER_VARS" || {
+    echo "Can not find util-vserver installation; aborting..."
+    exit 1
+}
+. "$UTIL_VSERVER_VARS"
+
+# take out the trash
+chattr -R -i "$VROOTDIR/.vtmp"
+rm -rf "$VROOTDIR/.vtmp"
+
+mkdir -p "$VROOTDIR/.vcache"
+mkdir -p "$VROOTDIR/.vtmp"
+
+# loop forever
+while : ; do
+    [ $debug -ne 0 ] && echo "$(date) Checking the cache"
+    for i in $(seq 0 $(($slots - 1))) ; do
+	if [ ! -d "$VROOTDIR/.vcache/v$i" ] ; then
+	    echo "$(date) Caching v$i"
+	    # build image in .vtmp
+	    TMP=$(mktemp -d "$VROOTDIR/.vtmp/v$i.XXXXXX")
+	    "$PKGLIBDIR/vbuild" "$VROOTDIR/vserver-reference" "$TMP"
+	    RETVAL=$?
+	    # move it to .vcache when complete
+	    if [ $RETVAL -eq 0 ] ; then
+    	         # sanity check
+		vnewsize=$(du -s "$TMP" | awk "{ print \$1 }")
+		vrefsize=$(du -s "$VROOTDIR/vserver-reference" | awk "{ print \$1 }")
+		if [ $vnewsize -lt $vrefsize ] ; then
+		    echo "WARNING: Unexpected for 'du -s $VROOTDIR/$NAME'=$vnewsize to be less than 'du -s $VROOTDIR/vserver-reference'=$vrefsize"
+		fi
+
+		mv "$TMP" "$VROOTDIR/.vcache/v$i"
+		echo "$(date) v$i ready"
+	    else
+		echo "$(date) Error $RETVAL building v$i"
+		chattr -R -i "$TMP"
+		rm -rf "$TMP"
+	    fi
+	fi
+    done
+    [ $debug -ne 0 ] && echo "$(date) Sleeping for $period seconds"
+    sleep $period
+done
diff --git a/scripts/vserver b/scripts/vserver
index 79e553f..7aae608 100755
--- a/scripts/vserver
+++ b/scripts/vserver
@@ -30,7 +30,8 @@ USR_SBIN=$SBINDIR
 USR_LIB_VSERVER=$PKGLIBDIR
 
 VSERVER_CMD=$USR_SBIN/vserver
-CHBIND_CMD=$USR_SBIN/chbind
+WAITFOR_CMD="waitfor 60"
+VINIT_CMD=/etc/rc.vinit
 CHCONTEXT_CMD=$USR_SBIN/chcontext
 SAVE_S_CONTEXT_CMD=$USR_LIB_VSERVER/save_s_context
 CAPCHROOT_CMD=$USR_LIB_VSERVER/capchroot
@@ -74,114 +75,6 @@ testperm()
 		echo
 	fi
 }
-# Set the IP alias needed by a vserver
-ifconfig_iproot()
-{
-	if [ "$NODEV" = "" -a "$IPROOT" != "" -a "$IPROOT" != "0.0.0.0" -a "$IPROOT" != "ALL" ] ;then
-		# A vserver may have more than one IP
-		# The first alias is dev:vserver
-		# and the other are dev:vserver1,2,3 and so on
-		# An IP may hold the device. The following is valid
-		#	IPROOT="1.2.4.5 eth1:1.2.3.5"
-		#	IPROOTDEV=eth0
-		# The first IP 1.2.3.4 will go on eth0 and the other on eth1
-		# VLAN devices are also supported (eth0.231 for vlan 231)
-		SUFFIX=
-		for oneip in $IPROOT
-		do
-			IPDEV=$IPROOTDEV
-			MASK=$IPROOTMASK
-			BCAST=$IPROOTBCAST
-			# Split the device and IP if available
-			case $oneip in
-			*:*)
-				eval `echo $oneip | tr : ' ' | (read dev ip; echo oneip=$ip; echo IPDEV=$dev)`
-				;;
-			esac
-			# Split the IP and the netmask if available
-			case $oneip in
-			*/*)
-				eval `echo $oneip | tr / ' ' | (read ip msk; echo oneip=$ip; echo MASK=$msk)`
-				eval `$USR_LIB_VSERVER/ifspec "" "$oneip" "$MASK" "$BCAST"`
-				;;
-			esac
-			if [ "$IPDEV" != "" ] ; then
-				case $IPDEV in
-				*.*)
-					if [ ! -f /proc/net/vlan/$IPDEV ] ; then
-						/sbin/vconfig add `echo $IPDEV | tr . ' '`
-						# Put a dummy IP
-						/sbin/ifconfig $IPDEV 127.0.0.1
-					fi
-					;;
-				esac
-				# Compute the default netmask, if missing
-				eval `$USR_LIB_VSERVER/ifspec $IPDEV "$oneip" "$MASK" "$BCAST"`
-				IPROOTMASK=$NETMASK
-				IPROOTBCAST=$BCAST
-				#echo /sbin/ifconfig $IPDEV:$1$SUFFIX $oneip netmask $IPROOTMASK broadcast $IPROOTBCAST
-				/sbin/ifconfig $IPDEV:$1$SUFFIX $oneip netmask $IPROOTMASK broadcast $IPROOTBCAST
-			fi
-			if [ "$SUFFIX" = "" ] ; then
-				SUFFIX=1
-			else
-				SUFFIX=`expr $SUFFIX + 1`
-			fi
-		done
-	fi
-	if [ "$IPROOTBCAST" = "" ] ; then
-		IPROOTBCAST=255.255.255.255
-	fi
-}
-ifconfig_iproot_off()
-{
-	if [ "$NODEV" = "" -a "$IPROOT" != "" -a "$IPROOT" != "0.0.0.0" -a "$IPROOT" != "ALL"  -a "$IPROOTDEV" != "" ] ;then
-		SUFFIX=
-		for oneip in $IPROOT
-		do
-			IPDEV=$IPROOTDEV
-			# Split the device and IP if available
-			case $oneip in
-			*:*)
-				eval `echo $oneip | tr : ' ' | (read dev ip; echo IPDEV=$dev)`
-				;;
-			esac
-			/sbin/ifconfig $IPDEV:$1$SUFFIX down 2>/dev/null
-			if [ "$SUFFIX" = "" ] ; then
-				SUFFIX=1
-			else
-				SUFFIX=`expr $SUFFIX + 1`
-			fi
-		done
-	fi
-}
-# Split an IPROOT definition, trash the devices and
-# compose a set of --ip option for chbind
-setipopt(){
-	RET=
-	IPS="$*"
-	if [ "$IPS" = "" ] ; then
-		IPS=0.0.0.0
-	fi
-	if [ "$1" = "ALL" ] ; then
-		IPS=`$USR_LIB_VSERVER/listdevip`
-	fi
-	for oneip in $IPS
-	do
-		# Split the device and IP if available
-		case $oneip in
-		*:*)
-			eval `echo $oneip | tr : ' ' | (read dev ip; echo oneip=$ip)`
-			;;
-		esac
-		#case $oneip in
-		#*/*)
-		#	eval `echo $oneip | tr / ' ' | (read ip msk; echo oneip=$ip)`
-		#	;;
-		#esac
-		echo --ip $oneip
-	done
-}
 
 # Extract the initial runlevel from the vserver inittab
 get_initdefault()
@@ -202,6 +95,28 @@ readlastconf()
 	export PROFILE
 	. /etc/vservers/$1.conf
 }
+
+# Wait for a process to finish for $1 seconds.
+waitfor()
+{
+	timeout=$1
+	shift
+	# Background the process.
+	$@ &
+	# Wait for it to finish.
+	while [ $timeout -gt 0 ] ; do
+		sleep 1
+		kill -0 $! 2>/dev/null || break
+		timeout=$(($timeout - 1))
+	done
+	# Try nicely terminating it, then just kill it.
+	if [ $timeout -eq 0 ] ; then
+		kill -TERM $! && kill -0 $! 2>/dev/null && kill -KILL $!
+	fi
+	# Cleanup.
+	wait
+}
+
 usage()
 {
 	echo vserver [ options ] server-name command ...
@@ -224,10 +139,6 @@ usage()
 	echo " status  : Tells some information about a vserver"
 	echo " chkconfig : It turns a server on or off in a vserver"
 	echo
-	echo "--nodev  : Do not configure the IP aliases of the vserver"
-	echo "           Useful to enter a vserver without enabling its network"
-	echo "           and avoiding conflicts with another copy of this vserver"
-	echo "           running elsewhere"
 	echo "--silent : No informative messages about vserver context and IP numbers"
 	echo "           Useful when you want to redirect the output"
 }
@@ -248,15 +159,11 @@ calculateCaps()
 }
 
 SILENT=
-NODEV=
 while true
 do
 	if [ "$1" = "--silent" ] ; then
 		SILENT=--silent
 		shift
-	elif [ "$1" = "--nodev" ] ; then
-		NODEV=--nodev
-		shift
 	else
 		break
 	fi
@@ -395,7 +302,8 @@ S_FLAGS="lock nproc"
 # ULIMIT="-HS -u 200"
 # The example above, combined with the nproc S_FLAGS will limit the
 # vserver to a maximum of 200 processes
-ULIMIT="-HS -u 1000"
+#ULIMIT="-HS -u 1000"
+ULIMIT=""
 # You can set various capabilities. By default, the vserver are run
 # with a limited set, so you can let root run in a vserver and not
 # worry about it. He can't take over the machine. In some cases
@@ -443,15 +351,10 @@ elif [ "$2" = "start" ] ; then
 	if ! $VSERVER_CMD $1 running
 	then
 		test -x /etc/vservers/$1.sh && /etc/vservers/$1.sh pre-start $1
-		IPROOT=
-		IPROOTMASK=
-		IPROOTBCAST=
-		IPROOTDEV=
 		S_NICE=
 		S_FLAGS=
 		. /etc/vservers/$1.conf
 		export PROFILE
-		ifconfig_iproot $1
 		cd $VROOTDIR/$1 || exit 1
 
 		if [ "$PROFILE" != "" ] ; then
@@ -539,12 +442,14 @@ elif [ "$2" = "start" ] ; then
 		# We switch to $VROOTDIR/$1 now, because after the
 		# security context switch $VROOTDIR directory becomes a dead zone.
 		cd $VROOTDIR/$1
-		IPOPT=`setipopt $IPROOT`
 		export PATH=$DEFAULTPATH
-		$NICECMD $CHBIND_CMD $SILENT $IPOPT --bcast $IPROOTBCAST \
-			$CHCONTEXT_CMD $SILENT $DISCONNECT $CAPS $FLAGS $CTXOPT $HOSTOPT $DOMAINOPT --secure \
-			$SAVE_S_CONTEXT_CMD /var/run/vservers/$1.ctx \
-			$CAPCHROOT_CMD $CHROOTOPT . $STARTCMD
+		# XXX execute /etc/rc.vinit first for backward compatibility
+		for CMD in "$VINIT_CMD $2" "$STARTCMD" ; do
+			$NICECMD \
+				$CHCONTEXT_CMD $SILENT $DISCONNECT $CAPS $FLAGS $CTXOPT $HOSTOPT $DOMAINOPT --secure \
+				$SAVE_S_CONTEXT_CMD /var/run/vservers/$1.ctx \
+				$CAPCHROOT_CMD $CHROOTOPT . $CMD
+		done
 		sleep 2
 		test -x /etc/vservers/$1.sh && /etc/vservers/$1.sh post-start $1
 	fi
@@ -575,17 +480,12 @@ elif [ "$2" = "status" ] ; then
 	fi
 elif [ "$2" = "stop" ] ; then
 	echo Stopping the virtual server $1
-	IPROOT=
-	IPROOTMASK=
-	IPROOTBCAST=
-	IPROOTDEV=
 	CAPS=
 	IS_MINIT=
 	readlastconf $1
 	if $VSERVER_CMD $1 running
 	then
 		test -x /etc/vservers/$1.sh && /etc/vservers/$1.sh pre-stop $1
-		ifconfig_iproot $1
 		cd $VROOTDIR/$1
 		mountproc $VROOTDIR/$1
 		# The fakeinit flag tell us how to turn off the server
@@ -625,11 +525,12 @@ elif [ "$2" = "stop" ] ; then
 		calculateCaps $S_CAPS
 
 		cd $VROOTDIR/$1
-		IPOPT=`setipopt $IPROOT`
 		export PATH=$DEFAULTPATH
-		$CHBIND_CMD $SILENT $IPOPT --bcast $IPROOTBCAST \
-			$CHCONTEXT_CMD $SILENT $CAPS --secure --ctx $S_CONTEXT \
-			$CAPCHROOT_CMD . $STOPCMD
+		# XXX execute /etc/rc.vinit first for backward compatibility
+		for CMD in "$VINIT_CMD $2" "$STOPCMD" ; do
+			$WAITFOR_CMD $CHCONTEXT_CMD $SILENT $CAPS --secure --ctx $S_CONTEXT \
+				$CAPCHROOT_CMD . $CMD
+		done
 
 		if test "$IS_MINIT"; then
 		    echo "Waiting for minit finish-signal"
@@ -641,8 +542,7 @@ elif [ "$2" = "stop" ] ; then
 		fi
 
 		echo Killing all processes
-		$CHBIND_CMD --silent $IPOPT --bcast $IPROOTBCAST \
-			$CHCONTEXT_CMD $CAPS --secure --silent --ctx $S_CONTEXT \
+		$CHCONTEXT_CMD $CAPS --secure --silent --ctx $S_CONTEXT \
 			$VSERVERKILLALL_CMD
 	fi
 	# We umount anyway, because "enter" establish the mount
@@ -650,7 +550,6 @@ elif [ "$2" = "stop" ] ; then
 	umountproc $VROOTDIR/$1
 	cd /
 	test -x /etc/vservers/$1.sh && /etc/vservers/$1.sh post-stop $1
-	ifconfig_iproot_off $1
 elif [ "$2" = "restart" ] ; then
 	if $0 $1 running
 	then
@@ -667,14 +566,9 @@ elif [ "$2" = "suexec" ] ; then
 		echo "vserver vserver-name suexec user command [ args ... ]" >&2
 		exit 1
 	else
-		IPROOT=
-		IPROOTMASK=
-		IPROOTBCAST=
-		IPROOTDEV=
 		readlastconf $1
 		. /etc/vservers/$1.conf
 		cd $VROOTDIR/$1
-		ifconfig_iproot $1
 		mountproc $VROOTDIR/$1
 		PS1="[\u@vserver:$1 \W]"
 		export PS1
@@ -718,10 +612,8 @@ elif [ "$2" = "suexec" ] ; then
 		then
 			. /var/run/vservers/$VSERVER.ctx
 			cd $VROOTDIR/$VSERVER
-			IPOPT=`setipopt $IPROOT`
 			export PATH=$DEFAULTPATH
-			exec $CHBIND_CMD $SILENT $IPOPT --bcast $IPROOTBCAST \
-				$CHCONTEXT_CMD $SILENT $FLAGS $CAPS --secure --ctx $S_CONTEXT \
+			exec $CHCONTEXT_CMD $SILENT $FLAGS $CAPS --secure --ctx $S_CONTEXT \
 				$CAPCHROOT_CMD --suid $USERID . "$@"
 		else
 			test -x /etc/vservers/$1.sh && /etc/vservers/$1.sh pre-start $1
@@ -740,10 +632,8 @@ elif [ "$2" = "suexec" ] ; then
 			fi
 			mkdir -p /var/run/vservers
 			cd $VROOTDIR/$VSERVER
-			IPOPT=`setipopt $IPROOT`
 			export PATH=$DEFAULTPATH
-			exec $CHBIND_CMD $SILENT $IPOPT --bcast $IPROOTBCAST \
-				$CHCONTEXT_CMD $SILENT $FLAGS $CAPS --secure $CTXOPT $HOSTOPT $DOMAINOPT \
+			exec $CHCONTEXT_CMD $SILENT $FLAGS $CAPS --secure $CTXOPT $HOSTOPT $DOMAINOPT \
 				$SAVE_S_CONTEXT_CMD /var/run/vservers/$VSERVER.ctx \
 				$CAPCHROOT_CMD --suid $USERID $CHROOTOPT . "$@"
 		fi
@@ -751,15 +641,15 @@ elif [ "$2" = "suexec" ] ; then
 elif [ "$2" = "exec" ] ; then
 	VSERV=$1
 	shift; shift
-	exec $0 $NODEV $SILENT $VSERV suexec root "$@"
+	exec $0 $SILENT $VSERV suexec root "$@"
 elif [ "$2" = "enter" ] ; then
 	testperm $1
-	exec $0 $NODEV $SILENT $1 exec /bin/bash -login
+	exec $0 $SILENT $1 exec /bin/bash -login
 elif [ "$2" = "service" ] ; then
 	VSERVER=$1
 	shift
 	shift
-	exec $0 $NODEV $SILENT $VSERVER exec /sbin/service "$@"
+	exec $0 $SILENT $VSERVER exec /sbin/service "$@"
 elif [ "$2" = "chkconfig" ] ; then
 	VSERVER=$1
 	LEVELS=()
diff --git a/scripts/vuseradd b/scripts/vuseradd
new file mode 100755
index 0000000..9c9457e
--- /dev/null
+++ b/scripts/vuseradd
@@ -0,0 +1,92 @@
+#!/bin/bash
+#
+# useradd(8) wrapper for vservers
+#
+# Copyright (c) 2004  The Trustees of Princeton University (Trustees).
+#
+# $Id: vuseradd,v 1.18 2004/11/17 20:34:25 mef Exp $
+#
+
+: ${UTIL_VSERVER_VARS:=$(dirname $0)/util-vserver-vars}
+test -e "$UTIL_VSERVER_VARS" || {
+    echo "Can not find util-vserver installation; aborting..."
+    exit 1
+}
+. "$UTIL_VSERVER_VARS"
+
+usage()
+{
+    echo "usage: $0 name"
+    exit 1
+}
+
+[ -z "$1" ] && usage
+NAME=$1
+
+# add slices group if not already present
+groupadd slices 2>/dev/null || :
+
+# add user
+useradd -g slices -s /bin/vsh $NAME
+
+USERID=$(awk -F: "\$1 == \"$NAME\" { print \$3 }" < /etc/passwd)
+GROUPID=$(awk -F: "\$1 == \"slices\" { print \$3 }" < /etc/group)
+
+# create vserver configuration file
+if [ ! -f /etc/vservers/$NAME.conf ] ; then
+    sed \
+	-e "s/.*S_CONTEXT=.*/S_CONTEXT=$USERID/" \
+	-e "s/.*ONBOOT=.*/ONBOOT=yes/" \
+	< $PKGLIBDIR/sample.conf \
+	> /etc/vservers/$NAME.conf
+fi
+
+if [ ! -d "$VROOTDIR/$NAME" ] ; then
+    # check the cache
+    shopt -s nullglob
+    for i in "$VROOTDIR/.vcache/"* ; do
+	[ -d "$i" ] && mv "$i" "$VROOTDIR/$NAME" && break
+    done
+    # build vserver
+    if [ ! -d "$VROOTDIR/$NAME" ] ; then
+	# build image in .vtmp
+	TMP=$(mktemp -d "$VROOTDIR/.vtmp/$NAME.XXXXXX")
+	"$PKGLIBDIR/vbuild" "$VROOTDIR/vserver-reference" "$TMP"
+	RETVAL=$?
+	# move it to .vcache when complete
+	if [ $RETVAL -ne 0 ] ; then 
+	    echo "Error $RETVAL building $VROOTDIR/$NAME"
+	    chattr -R -i "$TMP"
+	    rm -rf "$TMP" /etc/vservers/$NAME.conf /var/run/vservers/$NAME.ctx
+	    userdel -r $NAME
+	    exit $RETVAL
+	else
+	    # sanity check
+	    vnewsize=$(du -s "$TMP" | awk "{ print \$1 }")
+	    vrefsize=$(du -s "$VROOTDIR/vserver-reference" | awk "{ print \$1 }")
+	    if [ $vnewsize -lt $vrefsize ] ; then
+		echo "WARNING: Unexpected for 'du -s $VROOTDIR/$NAME'=$vnewsize to be less than 'du -s $VROOTDIR/vserver-reference'=$vrefsize"
+	    fi
+
+	    mv "$TMP" "$VROOTDIR/$NAME"
+	fi
+    fi
+fi
+
+if [ -d "$VROOTDIR/$NAME" ] ; then
+    # fix permissions
+    chmod 755 "$VROOTDIR/$NAME"
+
+    # add user in vserver
+    vserver $NAME suexec root groupadd -g $GROUPID slices
+    vserver $NAME suexec root useradd -u $USERID -g $GROUPID -p '' $NAME
+
+    # add an unrestricted entry to /etc/sudoers file
+    if [ -f "$VROOTDIR/$NAME/etc/sudoers" ] && \
+       ! grep -q "^$NAME" "$VROOTDIR/$NAME/etc/sudoers" ; then
+	echo "$NAME	ALL=(ALL)	ALL" >> "$VROOTDIR/$NAME/etc/sudoers"
+    fi
+fi
+
+# turn resource management on for vserver $NAME
+service resman start $NAME
diff --git a/scripts/vuserdel b/scripts/vuserdel
new file mode 100755
index 0000000..d24c479
--- /dev/null
+++ b/scripts/vuserdel
@@ -0,0 +1,47 @@
+#!/bin/bash
+#
+# userdel(8) wrapper for vservers
+#
+# Copyright (c) 2004  The Trustees of Princeton University (Trustees).
+#
+# $Id: vuserdel,v 1.4 2004/10/20 21:45:43 mef Exp $
+#
+
+: ${UTIL_VSERVER_VARS:=$(dirname $0)/util-vserver-vars}
+test -e "$UTIL_VSERVER_VARS" || {
+    echo "Can not find util-vserver installation; aborting..."
+    exit 1
+}
+. "$UTIL_VSERVER_VARS"
+
+usage()
+{
+    echo "usage: $0 name"
+    exit 1
+}
+
+[ -z "$1" ] && usage
+NAME=$1
+
+# stop vserver
+vserver $NAME stop
+
+# turn resource management off for vserver $NAME
+service resman stop $NAME
+
+# delete user
+userdel -r $NAME
+
+# remove vserver configuration file
+rm -f /etc/vservers/$NAME.conf
+
+# remove vserver profile
+rm -f /var/run/vservers/$NAME.ctx
+
+# destroy vserver
+if [ -d $VROOTDIR/$NAME ] ; then
+    TMP=$(mktemp -d "$VROOTDIR/.vtmp/$NAME.XXXXXX")
+    mv "$VROOTDIR/$NAME" "$TMP"
+    chattr -R -i "$TMP"
+    rm -rf "$TMP"
+fi
diff --git a/src/Makefile-files b/src/Makefile-files
index 2d2586e..b31a2ae 100644
--- a/src/Makefile-files
+++ b/src/Makefile-files
@@ -39,12 +39,17 @@ src_sbin_PRGS		=  src/chbind \
 			   src/chcontext \
 			   src/rebootmgr \
 			   src/reducecap \
-			   src/vlimit \
 			   src/vdu \
+			   src/vsh \
+			   src/vdlimit \
 			   src/vfiles \
 			   src/vkill \
 			   src/vserver-stat
 
+
+src_sbin_PRGS_broken 	=  src/vlimit
+
+
 src_GENFILES		=  src/setattr
 
 src_capchroot_SOURCES		=  src/capchroot.c
@@ -76,6 +81,12 @@ src_vkill_SOURCES		=  src/vkill.c
 src_vkill_LDADD			=  lib/libvserver.a
 src_vkill_CPPFLAGS		=  $(AM_CPPFLAGS) -DLEGACYDIR=\"$(legacydir)\"
 
+src_vsh_SOURCES			=  src/vsh.c
+src_vsh_LDADD			=  lib/libvserver.a
+
+src_vdlimit_SOURCES		=  src/vdlimit.c
+src_vdlimit_LDADD		=  lib/libvserver.a
+
 src_showattr_SOURCES		=  src/showattr.c
 src_showperm_SOURCES		=  src/showperm.c
 src_vbuild_SOURCES		=  src/vbuild.cc src/vutil.cc
diff --git a/src/chcontext.c b/src/chcontext.c
index 236e0cc..1b5275a 100644
--- a/src/chcontext.c
+++ b/src/chcontext.c
@@ -122,6 +122,7 @@ int main (int argc, char *argv[])
 	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)
diff --git a/src/dlimit.h b/src/dlimit.h
new file mode 100644
index 0000000..5cbb1a1
--- /dev/null
+++ b/src/dlimit.h
@@ -0,0 +1,76 @@
+#ifndef _VX_DLIMIT_H
+#define _VX_DLIMIT_H
+
+#include "virtual.h"
+// #include "switch.h"
+
+/*  inode vserver commands */
+
+#define VCMD_add_dlimit		VC_CMD(DLIMIT, 1, 0)
+#define VCMD_rem_dlimit		VC_CMD(DLIMIT, 2, 0)
+
+#define VCMD_set_dlimit		VC_CMD(DLIMIT, 5, 0)
+#define VCMD_get_dlimit		VC_CMD(DLIMIT, 6, 0)
+
+
+struct  vcmd_ctx_dlimit_base_v0 {
+	char *name;
+	uint32_t flags;
+};
+
+struct  vcmd_ctx_dlimit_v0 {
+	char *name;
+	uint32_t space_used;			/* used space in kbytes */
+	uint32_t space_total;			/* maximum space in kbytes */
+	uint32_t inodes_used;			/* used inodes */
+	uint32_t inodes_total;			/* maximum inodes */
+	uint32_t reserved;			/* reserved for root in % */
+	uint32_t flags;
+};
+
+#define CDLIM_UNSET             (0ULL)
+#define CDLIM_INFINITY          (~0ULL)
+#define CDLIM_KEEP              (~1ULL)
+
+
+#ifdef	__KERNEL__
+
+struct super_block;
+
+struct dl_info {
+	struct hlist_node dl_hlist;		/* linked list of contexts */
+	struct rcu_head dl_rcu;			/* the rcu head */
+	xid_t dl_xid;				/* context id */
+	atomic_t dl_usecnt;			/* usage count */
+	atomic_t dl_refcnt;			/* reference count */
+
+	struct super_block *dl_sb;		/* associated superblock */
+
+	struct rw_semaphore dl_sem;		/* protect the values */
+
+	uint64_t dl_space_used;			/* used space in bytes */
+	uint64_t dl_space_total;		/* maximum space in bytes */
+	uint32_t dl_inodes_used;		/* used inodes */
+	uint32_t dl_inodes_total;		/* maximum inodes */
+
+	unsigned int dl_nrlmult;		/* non root limit mult */
+};
+
+extern void rcu_free_dl_info(void *);
+extern void unhash_dl_info(struct dl_info *);
+
+struct kstatfs;
+
+extern void vx_vsi_statfs(struct super_block *, struct kstatfs *);
+
+
+extern int vc_add_dlimit(uint32_t, void __user *);
+extern int vc_rem_dlimit(uint32_t, void __user *);
+
+extern int vc_set_dlimit(uint32_t, void __user *);
+extern int vc_get_dlimit(uint32_t, void __user *);
+
+
+#endif	/* __KERNEL__ */
+
+#endif	/* _VX_DLIMIT_H */
diff --git a/src/vdu.c b/src/vdu.c
index 55f6082..b6cfc59 100644
--- a/src/vdu.c
+++ b/src/vdu.c
@@ -1,4 +1,4 @@
-// $Id: vdu.c,v 1.1 2003/09/29 22:01:57 ensc Exp $
+// $Id: vdu-new.c,v 1.2 2004/08/17 14:44:14 mef-pl_kernel Exp $
 
 // Copyright (C) 2003 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
 // based on vdu.cc by Jacques Gelinas
@@ -17,6 +17,8 @@
 // along with this program; if not, write to the Free Software
 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
+#define _LARGEFILE64_SOURCE
+
 #include <stdlib.h>
 #include <stdio.h>
 #include <sys/stat.h>
@@ -26,89 +28,229 @@
 #include <dirent.h>
 #include <errno.h>
 #include <string.h>
+#include <sys/ioctl.h>
+
+#include <assert.h>
+
+#include "vdu.h"
+
+HashTable tbl;
+
+static int // boolean
+INOPut(PHashTable tbl, ino64_t* key, struct stat64 **val){
+    return Put(tbl, key, val);
+}
 
 __extension__ typedef long long		longlong;
+//__extension__ typedef long		longlong;
+
+static longlong inodes;
+static longlong blocks;
+static longlong size;
+
+static short verbose = 0;
+
+static inline void warning(char *s) {
+    fprintf(stderr,"%s (%s)\n",s,strerror(errno));    
+}
+
+void panic(char *s) {
+    warning(s);
+    exit(2);
+}
 
-static int vdu_onedir (char const *path, longlong *size)
+static void vdu_onedir (char const *path)
 {
-	int ret = -1;
-	int dirfd = open (path,O_RDONLY);	// A handle to speed up
-												// chdir
-	if (dirfd == -1){
-		fprintf (stderr,"Can't open directory %s (%s)\n",path
-			,strerror(errno));
-	}else{
-	        DIR *dir;
-
-		fchdir (dirfd);
-		dir = opendir (".");
-		if (dir == NULL){
-			fprintf (stderr,"Can't open (opendir) directory %s (%s)\n",path
-				,strerror(errno));
-		}else{
-			struct stat dirst;
-			struct dirent *ent;
-			longlong dirsize = 0;
-
-			ret = 0;
-			lstat (".",&dirst);
-			while ((ent=readdir(dir))!=NULL){
-				struct stat st;
-				if (lstat(ent->d_name,&st)==-1){
-					fprintf (stderr,"Can't stat %s/%s (%s)\n",path
-						,ent->d_name,strerror(errno));
-					ret = -1;
-					break;
-				}else if (S_ISREG(st.st_mode)){
-					if (st.st_nlink == 1){
-						dirsize += st.st_size;
-					}
-				}else if (S_ISDIR(st.st_mode) && st.st_dev == dirst.st_dev){
-					if (strcmp(ent->d_name,".")!=0
-						&& strcmp(ent->d_name,"..")!=0){
-					        char	*tmp = malloc(strlen(path) + strlen(ent->d_name) + 2);
-						if (tmp==0) ret=-1;
-						else {
-						  strcpy(tmp, path);
-						  strcat(tmp, "/");
-						  strcat(tmp, ent->d_name);
-						  ret = vdu_onedir(tmp,&dirsize);
-						  free(tmp);
-						  fchdir (dirfd);
-						}
-					}
-				}
-			}
-			closedir (dir);
-			*size += dirsize;
+    char const *foo = path;
+    struct stat64 dirst, st;
+    struct dirent *ent;
+    char *name;
+    DIR *dir;
+    int dirfd;
+    longlong dirsize, dirinodes, dirblocks;
+
+    dirsize = dirinodes = dirblocks = 0;
+
+    // A handle to speed up chdir
+    if ((dirfd = open (path,O_RDONLY)) == -1) {
+	fprintf (stderr,"Can't open directory %s\n",path);
+	panic("open failed");
+    }
+
+    if (fchdir (dirfd) == -1) {
+	fprintf (stderr,"Can't fchdir directory %s\n",path);
+	panic("fchdir failed");
+    }
+
+    if (fstat64 (dirfd,&dirst) != 0) {
+	fprintf (stderr,"Can't lstat directory %s\n",path);
+	panic("lstat failed");
+    }
+
+    if ((dir = opendir (".")) == NULL) {
+	fprintf (stderr,"Can't open (opendir) directory %s\n",path);
+	panic("opendir failed");
+    }
+
+
+    /* Walk the directory entries and compute the sum of inodes,
+     * blocks, and disk space used. This code will recursively descend
+     * down the directory structure. 
+     */
+
+    while ((ent=readdir(dir))!=NULL){
+	if (lstat64(ent->d_name,&st)==-1){
+	    fprintf (stderr,"Can't stat %s/%s\n",path,ent->d_name);
+	    warning("lstat failed");
+	    continue;
+	}
+	
+	dirinodes ++;
+
+	if (S_ISREG(st.st_mode)){
+	    if (st.st_nlink > 1){
+		struct stat64 *val;
+		int nlink;
+
+		/* Check hash table if we've seen this inode
+		 * before. Note that the hash maintains a
+		 * (inode,struct stat) key value pair.
+		 */
+
+		val = &st;
+
+		(void) INOPut(&tbl,&st.st_ino,&val);
+
+		/* Note that after the INOPut call "val" refers to the
+		 * value entry in the hash table --- not &st.  This
+		 * means that if the inode has been put into the hash
+		 * table before, val will refer to the first st that
+		 * was put into the hashtable.  Otherwise, if it is
+		 * the first time it is put into the hash table, then
+		 * val will be equal to this &st.
+		 */
+		nlink = val->st_nlink;
+		nlink --;
+
+		/* val refers to value in hash tbale */
+		if (nlink == 0) {
+
+		    /* We saw all hard links to this particular inode
+		     * as part of this sweep of vdu. So account for
+		     * the size and blocks required by the file.
+		     */
+
+		    dirsize += val->st_size;
+		    dirblocks += val->st_blocks;
+
+		    /* Do not delete the (ino,val) tuple from the tbl,
+		     * as we need to handle the case when we are
+		     * double counting a file due to a bind mount.
+		     */
+		    val->st_nlink = 0;
+
+		} else if (nlink > 0) {
+		    val->st_nlink = nlink;
+		} else /* if(nlink < 0) */ {
+		    /* We get here when we are double counting nlinks
+		       due a bind mount. */
+
+		    /* DO NOTHING */
+		}
+	    } else {
+		dirsize += st.st_size;
+		dirblocks += st.st_blocks;
+	    }
+
+	} else if (S_ISDIR(st.st_mode)) {
+	    if ((st.st_dev == dirst.st_dev) &&
+		(strcmp(ent->d_name,".")!=0) &&
+		(strcmp(ent->d_name,"..")!=0)) {
+
+		dirsize += st.st_size;
+		dirblocks += st.st_blocks;
+
+		name = strdup(ent->d_name);
+		if (name==0) {
+		    panic("Out of memory\n");
 		}
-		close (dirfd);
+		vdu_onedir(name);
+		free(name);
+		fchdir(dirfd);
+	    }
+	} else {
+	    // dirsize += st.st_size;
+	    // dirblocks += st.st_blocks;
 	}
-	return ret;
+    }
+    closedir (dir);
+    close (dirfd);
+    if (verbose)
+	printf("%16lld %16lld %16lld %s\n",dirinodes, dirblocks, dirsize,foo);
+    inodes += dirinodes;
+    blocks += dirblocks;
+    size   += dirsize;
 }
 
-int main (int argc, char *argv[])
+static void
+Count(ino64_t* key, struct stat64* val) {
+    if(val->st_nlink) {
+	blocks += val->st_blocks;
+	size += val->st_size;
+	printf("ino=%16lld nlink=%d\n",val->st_ino, val->st_nlink);
+    }
+}
+
+int
+main (int argc, char **argv)
 {
-	int ret = -1;
-	if (argc < 2){
-		fprintf (stderr,"vdu version %s\n",VERSION);
-		fprintf (stderr,"vdu directory ...\n\n");
-		fprintf (stderr
-			,"Compute the size of a directory tree, ignoring files\n"
-			 "with more than one link.\n");
-	}else{
-		int i;
-
-		ret = 0;
-		for (i=1; i<argc && ret != -1; i++){
-			longlong size = 0;
-			long ksize;
-			
-			ret = vdu_onedir (argv[i],&size);
-			ksize = size >> 10;
-			printf ("%s\t%ldK\n",argv[i],ksize);
-		}
+    int startdir, i;
+
+    if (argc < 2){
+	fprintf (stderr,"vdu version %s\n",VERSION);
+	fprintf (stderr,"vdu directory ...\n\n");
+	fprintf (stderr,"Compute the size of a directory tree.\n");
+    }else{
+	if ((startdir = open (".",O_RDONLY)) == -1) {
+	    fprintf (stderr,"Can't open current working directory\n");
+	    panic("open failed");
 	}
-	return ret;
+
+	/* hash table support for hard link count */
+	(void) Init(&tbl,0,0);
+
+	for (i=1; i<argc; i++){
+	    inodes = blocks = size = 0;
+	    vdu_onedir (argv[i]);
+
+	    printf("%16lld %16lld %16lld %s\n",
+		   inodes, 
+		   blocks>>1, 
+		   size,
+		   argv[i]);
+	    if (fchdir (startdir) == -1) {
+		panic("fchdir failed");
+	    }
+	}
+
+	if(0) {
+	    /* show size & blocks for files with nlinks from outside of dir */
+	    inodes = blocks = size = 0;
+	    Iterate(&tbl,Count);
+	    printf("%16lld %16lld %16lld NOT COUNTED\n",
+		   inodes, 
+		   blocks, 
+		   size);
+	}
+
+	// Dispose(&tbl); this fails to delete all entries 
+	close(startdir);
+    }
+    return 0;
 }
 
+/*
+ * Local variables:
+ *  c-basic-offset: 4
+ * End:
+ */
diff --git a/src/vdu.h b/src/vdu.h
new file mode 100644
index 0000000..5405a59
--- /dev/null
+++ b/src/vdu.h
@@ -0,0 +1,374 @@
+#ifndef __VDU_H
+#define __VDU_H
+
+typedef ino64_t KEY;
+typedef KEY *PKEY;
+typedef struct stat64 VAL;
+typedef VAL *PVAL;
+
+static inline
+unsigned int
+HASH(PKEY key){
+    return (int) *key;
+}
+
+static inline
+unsigned int // boolean
+EQUAL(PKEY key1, PKEY key2){
+    return *key1 == *key2;
+}
+
+#ifndef MIN
+#define MIN(x,y) (((x)<(y))?(x):(y))
+#endif // MIN
+
+#ifndef MAX
+#define MAX(x,y) (((x)>(y))?(x):(y))
+#endif // MAX
+
+
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+// hash table support for efficient lookup of duplicate inodes */
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+
+#define Multiplier  (0x9e3779b9)
+#define MaxLogBuckets  (((sizeof (unsigned long))*8) - 2)
+#define MaxBuckets     (1<<MaxLogBuckets)
+#define MinLogBuckets  (4)
+#define MinBuckets     (1<<MinLogBuckets)
+
+// Thresholds for rehashing the table: *)
+// to avoid crazy oscillations, we must have MaxDensity > 2*MinDensity; *)
+// to avoid excessive probes, we must try to keep MaxDensity low. *)
+// Divide by 100 before using
+#define MaxDensity 75 /* max numEntries/NUMBER(buckets) */
+#define MinDensity 20 /* min numEntries/NUMBER(buckets) */
+#define IdealDensity 50
+#define BITSIZE(x) (sizeof(x)*8)
+
+#define NEW(type,num) ((type*)malloc(sizeof(type)*num))
+#define DISPOSE(ptr) (free((void*)ptr))
+
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+// Generic Hash Entry Type
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+
+typedef struct VoidList {
+  struct VoidList *tail;
+} VoidList, *PVoidList;
+
+typedef struct HashTable {
+  PVoidList *buckets;
+  unsigned int numBuckets;    // number of buckets
+  unsigned int minLogBuckets; // minimum value for Log_2(initial size) 
+  unsigned int logBuckets;    // CEILING(Log2(NUMBER(buckets^))) 
+  unsigned int maxEntries;    // maximum number of entries 
+  unsigned int minEntries;    // minimum number of entries 
+  unsigned int numEntries;    // current num of entries in table 
+  PVoidList cache;            // cache of removed elements 
+  int cacheSize;              // current size of the cache 
+  int maxCacheSize;           // maximum size, -1 means unbounded, 0 no cache 
+} HashTable, *PHashTable;
+
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+// Hash Prototypes
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+
+PHashTable
+Init(PHashTable tbl, unsigned int n, int maxCacheSize);
+
+void
+Dispose(PHashTable tbl);
+
+unsigned int
+Log_2(unsigned int x);
+
+void
+NewBuckets(PHashTable tbl, unsigned int logBuckets);
+
+//
+// Generic Hash Table support
+//
+
+PHashTable
+Init(PHashTable tbl, unsigned int n, int maxCacheSize){
+  int idealBuckets;
+  int minBuckets;
+  
+  idealBuckets = MIN(((n*100)/IdealDensity),MaxBuckets);
+  minBuckets = MAX(MinBuckets, idealBuckets);
+  tbl->minLogBuckets = Log_2(minBuckets);
+
+  NewBuckets(tbl, tbl->minLogBuckets);
+  tbl->numEntries = 0;
+  tbl->maxCacheSize = maxCacheSize;
+  tbl->cacheSize = 0;
+  tbl->cache = 0;
+  return tbl;
+} // Init()
+
+
+//
+// Internal procedures
+//
+
+unsigned int
+Log_2(unsigned int x){
+  // return CEILING(LOG_2(x))
+  unsigned int log = 0;
+  unsigned int n= 1;
+
+  assert(x != 0);
+  while ((log < MaxLogBuckets) && (x > n)){
+    log++; 
+    n += n;
+  }
+  return log;
+} // Log_2()
+
+void
+NewBuckets(PHashTable tbl, unsigned int logBuckets){
+  // Allocate "2^logBuckets" buckets.
+  unsigned int numBuckets = 1 << logBuckets;
+  PVoidList *b;
+  unsigned int i;
+
+  tbl->buckets = NEW(PVoidList, numBuckets);
+  tbl->numBuckets = numBuckets;
+  b = tbl->buckets;
+
+  for (i=0; i<tbl->numBuckets; i++){
+    b[i] = NULL;
+  }
+  tbl->logBuckets = logBuckets;
+  tbl->maxEntries = MaxDensity * numBuckets / 100;
+  tbl->minEntries = MinDensity * numBuckets / 100;
+} // NewBuckets()
+
+#ifndef NULL
+#define NULL (void*)0
+#endif // !NULL
+
+#ifndef TRUE
+#define TRUE 1
+#endif // !TRUE
+
+#ifndef FALSE
+#define FALSE 0
+#endif // !FALSE
+
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+// Type specific hash entry
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+typedef struct EntryList {
+  struct EntryList *tail;
+  KEY key;
+  VAL val;
+}EntryList, *PEntryList;
+
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+// Type specific Hash implementation functions
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+
+static
+void
+Rehash(PHashTable tbl, unsigned int logBuckets) {
+  // Reallocate "2^logBuckets" buckets, and rehash the entries into
+  // the new table.
+
+  PVoidList *oldBucketPointer;
+  PEntryList *ob, obi;
+  PEntryList *nb, *nbh;
+  PEntryList that, tail;
+  unsigned int index; 
+  unsigned int i;
+  unsigned int oldNumBuckets;
+
+  return;
+  assert(logBuckets <= MaxLogBuckets);
+  assert(logBuckets >= tbl->minLogBuckets);
+  oldBucketPointer = tbl->buckets;
+  ob = (PEntryList*)tbl->buckets;
+  oldNumBuckets = tbl->numBuckets;
+
+  NewBuckets(tbl, logBuckets);
+  nb = (PEntryList*)tbl->buckets;
+
+  for(i=0;i<oldNumBuckets;i++){
+    obi = ob[i];
+    that = obi;
+    while (that != NULL) {
+      index = (HASH(&(that->key))*Multiplier)>>(BITSIZE(unsigned long)-tbl->logBuckets);
+      nbh = &(nb[index]);
+      tail = that->tail;
+      that->tail = *nbh;
+      *nbh = that;
+      that = tail;
+    }
+  }
+  DISPOSE (oldBucketPointer);
+}
+
+static inline
+unsigned int // boolean
+Get(PHashTable tbl, PKEY key, PVAL *val){
+  PEntryList that;
+  unsigned int index;
+
+  index = (HASH(key)*Multiplier)>>(BITSIZE(unsigned long)-tbl->logBuckets);
+  that = (PEntryList)tbl->buckets[index];
+  while ((that != NULL) && !EQUAL(key,&(that->key))) {
+    that = that->tail;
+  }
+  if (that != NULL){
+    *val = &that->val;
+    return TRUE;
+  }
+  else {
+    return FALSE;
+  }
+} // Get()
+
+static inline 
+unsigned int // boolean
+Put(PHashTable tbl, PKEY key, PVAL *val){
+  PEntryList that;
+  PEntryList *first;
+  unsigned int index;
+  unsigned int res;
+
+  index = (HASH(key)*Multiplier)>>(BITSIZE(unsigned long)-tbl->logBuckets);
+  first = (PEntryList*)&(tbl->buckets[index]);
+  that = *first;
+  while ((that != NULL) && !EQUAL(key, &(that->key))){
+    that = that->tail;
+  }
+  
+  // found an entry in the hash table given above key
+  if (that != NULL){
+    res = TRUE;
+  }
+  else {
+    // check if we can reuse something from the cache
+    if (tbl->cache != NULL) {
+          that = (PEntryList)tbl->cache;
+          tbl->cache = (PVoidList)tbl->cache->tail;
+          that->key = *key;
+          that->tail = *first;
+          *first = that;
+    }
+    else {
+          that = NEW(EntryList,1);
+	  that->key = *key;
+	  that->tail = *first;
+	  *first = that;
+    }
+    that->val = **val;
+
+    tbl->numEntries++;
+    if ((tbl->logBuckets < MaxLogBuckets)
+	&& (tbl->numEntries > tbl->maxEntries)){
+      Rehash(tbl, tbl->logBuckets + 1); // too crowded
+    }
+    res = FALSE;
+  }
+  *val = &that->val;
+  return res;
+
+} // Put()
+
+static inline
+int
+Delete(PHashTable tbl,PKEY key){
+  PEntryList that, prev;
+  PEntryList *first;
+  unsigned int index;
+
+  index = (HASH(key)*Multiplier)>>(BITSIZE(unsigned long)-tbl->logBuckets);
+  first = (PEntryList*)&(tbl->buckets[index]);
+  that = *first;
+  prev = NULL;
+
+  while ((that != NULL) && !EQUAL(key, &(that->key))){
+    prev = that;
+    that = that->tail;
+  }
+  if (that != NULL) {
+    if (prev == NULL) {
+      *first = that->tail;
+    }
+    else {
+      prev->tail = that->tail;
+    }
+    if ((tbl->maxCacheSize == -1)||(tbl->cacheSize < tbl->maxCacheSize)) {
+      that->tail = (PEntryList)tbl->cache;
+      tbl->cache = (PVoidList)that;
+      tbl->cacheSize++;
+    }
+    else {
+      DISPOSE (that);
+    }
+    tbl->numEntries--;
+    if (tbl->maxCacheSize == 0) {
+      if ((tbl->logBuckets > tbl->minLogBuckets)
+	  && (tbl->numEntries < tbl->minEntries)) {
+	Rehash(tbl, tbl->logBuckets - 1); // too sparse
+      }
+    }
+    return TRUE;
+  }
+  else {
+    return FALSE;
+  }
+} // Delete()
+
+typedef void (*callback)(PKEY key, PVAL val);
+
+void
+Iterate(PHashTable tbl, callback fn)
+{
+  PVoidList that;
+  unsigned int i;
+  
+  for(i=0;i<tbl->numBuckets;i++) {
+    that = tbl->buckets[i];
+    while ( that != (PVoidList)0 ) {
+      PEntryList entry = (PEntryList)that;
+      fn(&entry->key,&entry->val);
+      that = that->tail;
+    }
+  }
+}
+
+void
+Dispose(PHashTable tbl)
+{
+  PVoidList that, next;
+  unsigned int i;
+
+  for(i=0;i<tbl->numBuckets;i++) {
+    that = tbl->buckets[i];
+    while( that != NULL) {
+        next = that->tail;
+        DISPOSE (that);
+        tbl->numEntries--;
+        that = next;
+    }
+  }
+  DISPOSE(tbl->buckets);
+  assert(tbl->numEntries = 0);
+} // Dispose;
+
+
+
+#endif // __VDU_H
diff --git a/src/vsh.c b/src/vsh.c
new file mode 100644
index 0000000..0fdd59c
--- /dev/null
+++ b/src/vsh.c
@@ -0,0 +1,604 @@
+/*
+ * Marc E. Fiuczynski <mef@cs.princeton.edu>
+ *
+ * Copyright (c) 2004 The Trustees of Princeton University (Trustees).
+ *
+ * vsh 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, or (at your option)
+ * any later version.
+ *
+ * vsh 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 Poptop; see the file COPYING.  If not, write to the Free
+ * Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+#include "compat.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <pwd.h>
+#include <unistd.h>
+#include <syscall.h>
+#include <sys/syscall.h>
+#include <asm/unistd.h>
+#include <sys/mount.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <ctype.h>
+
+//--------------------------------------------------------------------
+#include "linuxcaps.h"
+#include "vserver.h"
+
+/* Null byte made explicit */
+#define NULLBYTE_SIZE                    1
+
+/* Base for all vserver roots for chroot */
+#define VSERVER_ROOT_BASE       "/vservers"
+
+/* Change to root:root (before entering new context) */
+static int setuidgid_root()
+{
+	if (setgid(0) < 0) {
+		fprintf(stderr, "setgid error\n");
+		return -1;
+	}
+	if (setuid(0) < 0) {
+		fprintf(stderr, "setuid error\n");
+		return -1;
+	}
+	return 0;
+}
+
+static void compute_new_root(char *base, char **root, uid_t uid)
+{
+	int             root_len;
+	struct passwd   *pwd;
+
+	if ((pwd = getpwuid(uid)) == NULL) {
+		perror("vserver: getpwuid error ");
+		exit(1);
+	}
+
+	root_len = 
+		strlen(base) + strlen("/") +
+		strlen(pwd->pw_name)      + NULLBYTE_SIZE;
+	(*root) = (char *)malloc(root_len);
+	if ((*root) == NULL) {
+		perror("vserver: malloc error ");
+		exit(1);
+	}
+    
+	sprintf((*root), "%s/%s", base, pwd->pw_name);
+	(*root)[root_len - 1] = '\0';
+}
+
+/* Example: sandbox_root = /vservers/bnc, relpath = /proc/1 */
+static int sandbox_file_exists(char *sandbox_root, char *relpath)
+{
+	struct stat stat_buf;
+	char   *file;
+	int    len, exists = 0;
+
+	len = strlen(sandbox_root) + strlen(relpath) + NULLBYTE_SIZE;
+	if ((file = (char *)malloc(len)) == NULL) {
+		perror("vserver: malloc error ");
+		exit(1);
+	}
+	sprintf(file, "%s%s", sandbox_root, relpath);
+	file[len - 1] = '\0';
+	if (stat(file, &stat_buf) == 0) {
+		exists = 1;
+	}
+
+
+	free(file);
+	return exists;
+}
+
+static int proc_mounted(char *sandbox_root)
+{
+	return sandbox_file_exists(sandbox_root, "/proc/1");
+}
+
+static int devpts_mounted(char *sandbox_root)
+{
+	return sandbox_file_exists(sandbox_root, "/dev/pts/0");
+}
+
+static void mount_proc(char *sandbox_root,uid_t uid)
+{
+	char        *source = "/proc";
+	char        *target;
+	int         len;
+
+	len = strlen(sandbox_root) + strlen("/") + strlen("proc") + NULLBYTE_SIZE;
+	if ((target = (char *)malloc(len)) == NULL) {
+		perror("vserver: malloc error ");
+		exit(1);
+	}
+
+	sprintf(target, "%s/proc", sandbox_root);
+	target[len - 1] = '\0';
+	if (!proc_mounted(sandbox_root))
+		mount(source, target, "proc", MS_BIND | MS_RDONLY, NULL);
+
+	free(target);
+}
+
+static void mount_devpts(char *sandbox_root)
+{
+	char        *source = "/dev/pts";
+	char        *target;
+	int         len;
+    
+	len = strlen(sandbox_root) + strlen("/") + strlen("dev/pts") + NULLBYTE_SIZE;
+	if ((target = (char *)malloc(len)) == NULL) {
+		perror("vserver: malloc error ");
+		exit(1);
+	}
+
+	sprintf(target, "%s/dev/pts", sandbox_root);
+	target[len - 1] = '\0';
+	if (!devpts_mounted(sandbox_root))
+		mount(source, target, "devpts", 0, NULL);
+
+	free(target);
+}
+
+static int sandbox_chroot(uid_t uid)
+{
+	char *sandbox_root = NULL;
+
+	compute_new_root(VSERVER_ROOT_BASE,&sandbox_root, uid);
+	mount_proc(sandbox_root,uid);
+	mount_devpts(sandbox_root);
+	if (chroot(sandbox_root) < 0) {
+		fprintf(stderr,"vserver: chroot error (%s): ",sandbox_root);
+		perror("");
+		exit(1);
+	}
+	if (chdir("/") < 0) {
+		perror("vserver: chdir error ");
+		exit(1);
+	}
+	return 0;
+}
+
+#ifndef CAP_CONTEXT
+#  define CAP_CONTEXT	29
+#endif
+
+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_CONTEXT",		CAP_CONTEXT},
+	{NULL,0}
+};
+
+#define VSERVERCONF "/etc/vservers/"
+static unsigned get_remove_cap(char *name) {
+	FILE     *fb;
+	unsigned remove_cap;
+
+	char *vserverconf;
+	int vserverconflen;
+
+	remove_cap = /* NOTE: keep in sync with chcontext.c */
+		(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_CONTEXT)|
+		0
+		;
+
+	/*
+	 * find out which capabilities to put back in by reading the conf file 
+	 */
+
+	/* construct the pathname to the conf file */
+	vserverconflen = strlen(VSERVERCONF) + strlen(name) + strlen(".conf") + NULLBYTE_SIZE;
+	vserverconf    = (char *)malloc(vserverconflen);	
+	sprintf(vserverconf, "%s%s.conf", VSERVERCONF, name);
+	
+	/* open the conf file for reading */
+	fb = fopen(vserverconf,"r");
+	if (fb != NULL) {
+		unsigned cap;
+		size_t index;
+		size_t len;
+		char buffer[1000], *p;
+
+		/* the conf file file exist */ 
+		while((p=fgets(buffer,sizeof(buffer)-1,fb))!=NULL) {
+
+			/* walk past leading spaces */
+			index = 0;
+			len = strnlen(buffer,sizeof(buffer)-1);
+			while(isspace((int)buffer[index])) {
+				if (index < len) {
+					index++;
+				} else {
+					goto out;
+				}
+			}
+
+			if (buffer[index] == '#') continue;
+				
+			/* check if it is the S_CAPS */
+			if ((p=strstr(&buffer[index],"S_CAPS"))!=NULL) {
+				int j;
+				cap = 0;
+
+				/* what follows is a bunch of error
+				   checking to parse the S_CAPS="..."
+				   string */
+
+				/* adjust index into buffer */
+				index+= (p-&buffer[index])+strlen("S_CAPS");
+
+				/* skip over whitespace */
+				while(isspace((int)buffer[index])) {
+					if (index < len) {
+						index++;
+					} else {
+					/* parse error */
+						goto out;
+					}
+				}
+
+				/* expecting to see = sign */
+				if (buffer[index++]!='=') {
+					/* parse error */
+					goto out;
+				}
+
+				/* skip over whitespace */
+				while(isspace((int)buffer[index])) {
+					if (index < len) {
+						index++;
+					} else {
+						/* parse error */
+						goto out;
+					}
+				}
+
+				/* expecting to see the opening " */
+				if (buffer[index]!='"') {
+					/* parse error */
+					goto out;
+				}
+
+				/* check to see that we are still within bounds */
+				if (index < len) {
+					index++;
+				} else {
+					/* parse error */
+					goto out;
+				}
+
+				/* search for the closing " */
+				if((p=strstr(&buffer[index],"\""))==NULL) {
+					/* parse error */
+					goto out;
+				}
+
+				/* ok... we should now have a bunch of
+				   CAP keys words within the quotes */
+
+				for (j=0; tbcap[j].option != NULL; j++){
+					if ((p=strstr(buffer,tbcap[j].option))!=NULL){
+						len = strlen(tbcap[j].option);
+						if (((isspace(*(p-1))) || (*(p-1)=='"')) &&
+						    ((isspace(*(p+len))) || (*(p+len)=='"'))) {
+							cap |= (1<<tbcap[j].bit);
+						} else {
+							/* parse error */
+							goto out;
+						}
+					}
+				}
+				remove_cap &= ~cap;
+				break;
+			}
+		}
+ out:
+		/* close the conf file */
+		fclose(fb);
+	}
+	return remove_cap;
+}
+
+static int sandbox_processes(uid_t uid, unsigned remove_cap)
+{
+	int      context;
+	int      flags;
+
+	/* Unique context */
+	context = uid;
+
+	flags = 0;
+	flags |= 1; /* VX_INFO_LOCK -- cannot request a new vx_id */
+	/* flags |= 4; VX_INFO_NPROC -- limit number of procs in a context */
+
+	if (vc_new_s_context(context,remove_cap,flags) < 0) {
+		perror("vserver: new_s_context error ");
+		exit(1);
+	}
+	return 0;
+}
+
+
+void runas_slice_user(char *username)
+{
+	struct passwd *pwd;
+	char          *home_env, *logname_env, *mail_env, *shell_env, *user_env;
+	int           home_len, logname_len, mail_len, shell_len, user_len;
+	static char   *envp[10];
+
+	if ((pwd = getpwnam(username)) == NULL) {
+		perror("vserver: getpwnam error ");
+		exit(1);
+	}
+
+	if (setgid(pwd->pw_gid) < 0) {
+		perror("vserver: setgid error ");
+		exit(1);
+	}
+
+	if (setuid(pwd->pw_uid) < 0) {
+		perror("vserver: setuid error ");
+		exit(1);
+	}
+
+	if (chdir(pwd->pw_dir) < 0) {
+		perror("vserver: chdir error ");
+		exit(1);
+	}
+
+	home_len    = strlen("HOME=") + strlen(pwd->pw_dir) + NULLBYTE_SIZE;
+	logname_len = strlen("LOGNAME=") + strlen(username) + NULLBYTE_SIZE;
+	mail_len    = strlen("MAIL=/var/spool/mail/") + strlen(username) 
+		+ NULLBYTE_SIZE;
+	shell_len   = strlen("SHELL=") + strlen(pwd->pw_shell) + NULLBYTE_SIZE;
+	user_len    = strlen("USER=") + strlen(username) + NULLBYTE_SIZE;
+
+	home_env    = (char *)malloc(home_len);
+	logname_env = (char *)malloc(logname_len);
+	mail_env    = (char *)malloc(mail_len);
+	shell_env   = (char *)malloc(shell_len);
+	user_env    = (char *)malloc(user_len);
+
+	if ((home_env    == NULL)  || 
+	    (logname_env == NULL)  ||
+	    (mail_env    == NULL)  ||
+	    (shell_env   == NULL)  ||
+	    (user_env    == NULL)) {
+		perror("vserver: malloc error ");
+		exit(1);
+	}
+
+	sprintf(home_env, "HOME=%s", pwd->pw_dir);
+	sprintf(logname_env, "LOGNAME=%s", username);
+	sprintf(mail_env, "MAIL=/var/spool/mail/%s", username);
+	sprintf(shell_env, "SHELL=%s", pwd->pw_shell);
+	sprintf(user_env, "USER=%s", username);
+    
+	home_env[home_len - 1]       = '\0';
+	logname_env[logname_len - 1] = '\0';
+	mail_env[mail_len - 1]       = '\0';
+	shell_env[shell_len - 1]     = '\0';
+	user_env[user_len - 1]       = '\0';
+
+	envp[0] = home_env;
+	envp[1] = logname_env;
+	envp[2] = mail_env;
+	envp[3] = shell_env;
+	envp[4] = user_env;
+	envp[5] = 0;
+
+	if ((putenv(home_env)    < 0) ||
+	    (putenv(logname_env) < 0) ||
+	    (putenv(mail_env)    < 0) ||
+	    (putenv(shell_env)   < 0) ||
+	    (putenv(user_env)    < 0)) {
+		perror("vserver: putenv error ");
+		exit(1);
+	}
+}
+
+
+
+void slice_enter(char *context)
+{
+	struct passwd   *pwd;
+	unsigned remove_cap;
+	uid_t uid;
+
+	if ((pwd = getpwnam(context)) == NULL) {
+		fprintf(stderr,"vserver: getpwname(%s) failed",context);
+		exit(2);
+	}
+
+	context = (char*)malloc(strlen(pwd->pw_name)+NULLBYTE_SIZE);
+	if (!context) {
+		perror("vserver: malloc failed");
+		exit(2);
+	}
+	strcpy(context,pwd->pw_name);
+
+	if (setuidgid_root() < 0) { /* For chroot, new_s_context */
+		fprintf(stderr,"vserver: Could not setuid/setguid to root:root\n");
+		exit(2);
+	}
+
+	remove_cap = get_remove_cap(context);
+
+	uid = pwd->pw_uid;
+	if (sandbox_chroot(uid) < 0) {
+		fprintf(stderr, "vserver: Could not chroot to vserver root\n");
+		exit(2);
+	}
+
+	if (sandbox_processes(uid, remove_cap) < 0) {
+		fprintf(stderr, "vserver: Could not sandbox processes in vserver\n");
+		exit(2);
+	}
+}
+
+//--------------------------------------------------------------------
+
+#define DEFAULT_SHELL "/bin/sh"
+
+/* Exit statuses for programs like 'env' that exec other programs.
+   EXIT_FAILURE might not be 1, so use EXIT_FAIL in such programs.  */
+enum
+{
+  EXIT_CANNOT_INVOKE = 126,
+  EXIT_ENOENT = 127
+};
+
+extern void slice_enter(char *);
+extern void runas_slice_user(char *);
+
+int main(int argc, char **argv)
+{
+    char *context, *username, *shell;
+    struct passwd   *pwd;
+    uid_t           uid;
+    int index, i;
+
+    if (argv[0][0]=='-') 
+      index = 1;
+    else
+      index = 0;
+
+    uid = getuid();
+    if ((pwd = getpwuid(uid)) == NULL) {
+      fprintf(stderr,"vsh: getpwnam error failed for %d\n",uid); 
+      exit(1);
+    }
+
+    context = (char*)strdup(pwd->pw_name);
+    if (!context) {
+      perror("vsh: strdup failed");
+      exit(2);
+    }
+
+    /* enter vserver "context" */
+    slice_enter(context);
+
+    /* Now run as username in this context. Note that for PlanetLab's
+       vserver configuration the context name also happens to be the
+       "default" username within the vserver context.
+    */
+    username = context;
+    runas_slice_user(username);
+
+    /* With the uid/gid appropriately set. Let's figure out what the
+     * shell in the vserver's /etc/passwd is for the given username.
+     */
+    if ((pwd = getpwnam(username)) == NULL) {
+        fprintf(stderr,"vsh: getpwnam error failed for %s\n",username); 
+        exit(1);
+    }
+
+    /* Make sure pw->pw_shell is non-NULL.*/
+    if (pwd->pw_shell == NULL || pwd->pw_shell[0] == '\0') {
+      pwd->pw_shell = (char *) DEFAULT_SHELL;
+    }
+
+    shell = (char *)strdup(pwd->pw_shell);
+    if (!shell) {
+      perror("vsh: strdup failed");
+      exit(2);
+    }
+
+    /* Check whether 'su' or 'sshd' invoked us as a login shell or
+       not; did this above when testing argv[0]=='-'.
+    */
+    argv[0] = shell;
+    if (index == 1) {
+      char **args;
+      args = (char**)malloc(sizeof(char*)*(argc+2));
+      if (!args) {
+	perror("vsh: malloc failed");
+      }
+      args[0] = argv[0];
+      args[1] = "-l";
+      for(i=1;i<argc+1;i++) {
+	args[i+1] = argv[i];
+      }
+      argv = args;
+    }
+    (void) execvp(shell,argv);
+    {
+      int exit_status = (errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE);
+      exit (exit_status);
+    }
+
+    return 0; /* shutup compiler */
+}
diff --git a/sysv/Makefile-files b/sysv/Makefile-files
index 338a782..5d0864c 100644
--- a/sysv/Makefile-files
+++ b/sysv/Makefile-files
@@ -26,6 +26,7 @@ sysv_XTRAS		=  sysv/rebootmgr.subst \
 			   sysv/v_smb.subst \
 			   sysv/v_sshd.subst \
 			   sysv/v_xinetd.subst \
+			   sysv/vcached.subst \
 			   sysv/vservers.subst
 
 sysv_GENSCRPTS		=  sysv/rebootmgr \
@@ -37,11 +38,12 @@ sysv_GENSCRPTS		=  sysv/rebootmgr \
 			   sysv/v_smb \
 			   sysv/v_sshd \
 			   sysv/v_xinetd \
+			   sysv/vcached \
 			   sysv/vservers
 
 sysv_SCRPTS		=  $(sysv_GENSCRPTS)
 
-sysv_CFG		=  sysv/vservers.conf
+sysv_CFG		=  sysv/vservers.conf sysv/vcached.conf
 
 
 sysv/%:			sysv/%.subst
diff --git a/sysv/vcached.conf b/sysv/vcached.conf
new file mode 100644
index 0000000..4dd5206
--- /dev/null
+++ b/sysv/vcached.conf
@@ -0,0 +1,20 @@
+# number of images to keep cached
+slots=32
+
+# fill the cache periodically (seconds)
+period=$((60 * 15))
+
+# nice adjustment
+nice=10
+
+# PID file
+pidfile=/var/run/vcached.pid
+
+# log file
+logfile=/var/log/vcached.log
+
+# run in foreground
+foreground=0
+
+# debug
+debug=0
diff --git a/sysv/vcached.logrotate b/sysv/vcached.logrotate
new file mode 100644
index 0000000..203baba
--- /dev/null
+++ b/sysv/vcached.logrotate
@@ -0,0 +1,10 @@
+/var/log/vcached.log {
+    compress
+    daily
+    notifempty
+    rotate 5
+    missingok
+    postrotate
+        kill -HUP `cat /var/run/vcached.pid 2>/dev/null` 2>/dev/null || true
+    endscript
+}
diff --git a/sysv/vcached.subst b/sysv/vcached.subst
new file mode 100755
index 0000000..7714371
--- /dev/null
+++ b/sysv/vcached.subst
@@ -0,0 +1,56 @@
+#!/bin/sh
+#
+# chkconfig: 2345 65 80
+# description: vcached startup script
+# pidfile: /var/run/vcached.pid
+#
+. /etc/init.d/functions
+RETVAL=0
+USR_SBIN=/usr/sbin
+
+start() {
+    echo -n "Starting vcached: "
+    initlog -c $USR_SBIN/vcached
+    RETVAL=$?
+    [ "$RETVAL" -eq 0 ] && success $"vcached start" || failure $"vcached start"
+    echo
+    [ $RETVAL -eq 0 ] && touch /var/lock/subsys/vcached
+    return $RETVAL
+}
+
+stop() {
+    echo -n "Stopping vcached: "
+    if [[ -e /var/run/vcached.pid ]]; then
+        /bin/kill `cat /var/run/vcached.pid`
+        RETVAL=$?
+    else
+        RETVAL=1
+    fi
+    [ "$RETVAL" -eq 0 ] && success $"vcached shutdown" || failure $"vcached shutdown
+"
+    echo
+    rm -f /var/lock/subsys/vcached
+    rm -f /var/run/vcached.pid
+    return $RETVAL
+}    
+
+restart() {
+    stop
+    start
+}    
+
+case "$1" in
+    start)
+        start
+        ;;
+    stop)
+        stop
+        ;;
+    restart)
+        restart
+        ;;
+    *)
+        echo $"Usage: $0 {start|stop|restart}"
+        exit 1
+esac
+exit $?
diff --git a/sysv/vservers.conf b/sysv/vservers.conf
index 0f309e3..7f13fc1 100644
--- a/sysv/vservers.conf
+++ b/sysv/vservers.conf
@@ -2,6 +2,6 @@
 # BACKGROUND=yes
 # start the vservers on tty9, in background so the rest of the
 # boot process end early
-BACKGROUND=no
+BACKGROUND=yes
 
 
diff --git a/sysv/vservers.subst b/sysv/vservers.subst
index 7be797d..523f4fa 100755
--- a/sysv/vservers.subst
+++ b/sysv/vservers.subst
@@ -1,82 +1,82 @@
 #!/bin/sh
-# chkconfig: 345 98 10
+# chkconfig: 345 99 01
 # description: The vservers service is used to start and stop all
 #              the virtual servers.
 
 USR_SBIN=/usr/sbin
-
+VROOTDIR=/vservers
 
 # Print the vserver name in priority/alpha order
 sortserver(){
-	(
-	cd /etc/vservers
-	for serv in *.conf
-	do
-	        test -f "$serv" || continue
-
-		PRIORITY=100
-		. $serv
-		printf "%03d %s\n" $PRIORITY `basename $serv .conf`
-	done
-	) | sort $* | (while read a b; do echo $b; done)
+    (
+    cd /etc/vservers
+    for serv in *.conf ; do
+	test -f "$serv" || continue
+	PRIORITY=100
+	. $serv
+	printf "%03d %s\n" $PRIORITY `basename $serv .conf`
+    done
+    ) | sort $* | (while read a b; do echo $b; done)
 }
 
 startservers(){
-	echo "Starting the virtual servers"
-	cd /etc/vservers
-	for name in `sortserver`
-	do
-		ONBOOT=
-		. $name.conf
-		if [ "$ONBOOT" = "yes" ] ; then
-			$USR_SBIN/vserver $name start
-		else
-			echo virtual server $name not configured for on boot start
-		fi
-	done
+    echo "Starting the virtual servers"
+    cd /etc/vservers
+    for name in ${*:-`sortserver`} ; do
+	if ! test -f "$name.conf" ; then
+	    echo No configuration for this vserver: /etc/vservers/$name.conf
+	    continue
+	fi
+	ONBOOT=
+	BACKGROUND=no
+	if [ -f /etc/vservers.conf ] ; then
+	    . /etc/vservers.conf
+	fi
+	. $name.conf
+	if [ "$ONBOOT" = "yes" ] ; then
+	    mkdir -p $VROOTDIR/$name/var/log
+	    if [ "$BACKGROUND" = "yes" ] ; then
+		nohup setsid $USR_SBIN/vserver $name start >$VROOTDIR/$name/var/log/boot.log 2>&1 </dev/null &
+		sleep 1
+	    else
+		$USR_SBIN/vserver $name start 2>&1 </dev/null | tee $VROOTDIR/$name/var/log/boot.log
+	    fi
+	fi
+    done
 }
 
-BACKGROUND=off
-if [ -f /etc/vservers.conf ] ; then
-	. /etc/vservers.conf
-fi
-
-
 # See how we were called.
 case "$1" in
   start)
-	if [ "$BACKGROUND" = "yes" ] ; then
-		startservers >/dev/tty8 </dev/tty8 2>/dev/tty8 &
-	else
-		startservers
-	fi
+	shift
+	startservers $*
 	touch /var/lock/subsys/vservers
 	;;
   stop)
+	shift
 	echo "Stopping the virtual servers"
 	cd /etc/vservers
-	for name in `sortserver -r`
-	do
-		$USR_SBIN/vserver $name stop
+	for name in ${*:-`sortserver -r`} ; do
+	    $USR_SBIN/vserver $name stop
 	done
 	rm -f /var/lock/subsys/vservers
 	;;
   restart|force-reload)
-	$0 stop
-	$0 start
+	shift
+	$0 stop $*
+	$0 start $*
 	;;
   reload)
 	echo Not implemented
 	;;
   status)
 	cd /etc/vservers
-	for serv in *.conf
-	do
-		ONBOOT=no
-		name=`basename $serv .conf`
-		. $serv
-		echo -n ONBOOT=$ONBOOT " "
-		$USR_SBIN/vserver $name running
+	for serv in *.conf ; do
+	    ONBOOT=no
+	    name=`basename $serv .conf`
+	    . $serv
+	    echo -n ONBOOT=$ONBOOT " "
+	    $USR_SBIN/vserver $name running
 	done
 	;;
   *)
@@ -85,7 +85,3 @@ case "$1" in
 esac
 
 exit 0
-
-
-
-
diff --git a/util-vserver.spec b/util-vserver.spec
index dfb7941..244324c 100644
--- a/util-vserver.spec
+++ b/util-vserver.spec
@@ -1,13 +1,21 @@
+%define name util-vserver
+%define version 0.30
+%define release 6.planetlab%{?date:.%{date}}
+
+Vendor: PlanetLab
+Packager: PlanetLab Central <support@planet-lab.org>
+Distribution: PlanetLab 3.0
+URL: http://cvs.planet-lab.org/cvs/util-vserver
+
 %define __chattr	/usr/bin/chattr
 
 Summary:	Linux virtual server utilities
-Name:		util-vserver
-Version:	0.30
-Release:	0
+Name:		%{name}
+Version:	%{version}
+Release:	%{release}
 Epoch:		0
 Copyright:	GPL
 Group:		System Environment/Base
-URL:		http://savannah.nongnu.org/projects/util-vserver/
 Source0:	http://savannah.nongnu.org/download/util-vserver/stable.pkg/%version/%name-%version.tar.bz2
 Provides:	%name-devel = %epoch:%version-%release
 BuildRoot:	%_tmppath/%name-%version-%release-root
@@ -43,12 +51,17 @@ linuxconf.
 
 %prep
 %setup -q
+aclocal -I m4
+autoconf
+automake --add-missing
+# bootstrap to avoid BuildRequires of kernel-source
+for linux in $RPM_BUILD_DIR/linux-* /lib/modules/`uname -r`/build ; do
+   [[ -d $linux/include ]] && %configure --with-kerneldir=$linux --enable-linuxconf && break
+done
 
 
 %build
-%configure --enable-linuxconf
-%__make %{?_smp_mflags}
-
+make
 
 %install
 rm -rf $RPM_BUILD_ROOT
@@ -60,36 +73,57 @@ test "%_initrddir" = %_sysconfdir/init.d || {
 	mv ${RPM_BUILD_ROOT}%_sysconfdir/init.d/* ${RPM_BUILD_ROOT}%_initrddir/
 }
 
+mkdir -p ${RPM_BUILD_ROOT}/bin
+ln -f ${RPM_BUILD_ROOT}%_sbindir/vsh ${RPM_BUILD_ROOT}/bin/vsh
+
+install -D -m 644 sysv/vcached.logrotate ${RPM_BUILD_ROOT}/etc/logrotate.d/vcached
 
 %clean
 rm -rf $RPM_BUILD_ROOT
 
+%define services vcached vservers
 
-%define v_services	httpd named portmap sendmail smb sshd xinetd
-%post
-/sbin/chkconfig --add vservers
-/sbin/chkconfig --add rebootmgr
+%pre
+# 1 = install, 2 = upgrade/reinstall
+if [ $1 -eq 2 ] ; then
+    for i in %{services} ; do
+	[ "`/sbin/runlevel`" = "unknown" ] || service $i stop || :
+    done
+fi
 
-for i in %v_services; do
-	/sbin/chkconfig --add v_$i
+%post
+# 1 = install, 2 = upgrade/reinstall
+if [ $1 -eq 1 ] ; then
+    for i in %{services} ; do
+	chkconfig --add $i
+	chkconfig $i on
+    done
+fi
+for i in %{services} ; do
+    [ "`/sbin/runlevel`" = "unknown" ] || service $i start
 done
+if [ ! -f /etc/shells ] || ! grep -q '^/bin/vsh$' /etc/shells ; then
+    echo /bin/vsh >> /etc/shells
+fi
 
 %__chattr +t /vservers || :
 
 
-%preun
-test "$1" != 0 || for i in %v_services; do
-	/sbin/chkconfig --del v_$i
-done
-
-test "$1" != 0 || %{_initrddir}/rebootmgr stop &>/dev/null || :
-test "$1" != 0 || /sbin/chkconfig --del rebootmgr
-test "$1" != 0 || /sbin/chkconfig --del vservers
-
-
 %postun
-test "$1" = 0  || %{_initrddir}/rebootmgr condrestart >/dev/null || :
+# 0 = erase, 1 = upgrade
+if [ "$1" = 0 ] ; then
+    perl -i -n -e 'next if /^\/bin\/vsh$/; print' /etc/shells
+fi
 
+%preun
+# 0 = erase, 1 = upgrade
+if [ $1 -eq 0 ] ; then
+    for i in %{services} ; do
+	[ "`/sbin/runlevel`" = "unknown" ] || service $i stop || :
+	chkconfig $i off
+	chkconfig --del $i
+    done
+fi
 
 %files
 %defattr(-,root,root)
@@ -101,22 +135,32 @@ test "$1" = 0  || %{_initrddir}/rebootmgr condrestart >/dev/null || :
 %_mandir/man8/*
 %config %_initrddir/*
 %config(noreplace) /etc/vservers.conf
+%config(noreplace) /etc/vcached.conf
+/etc/logrotate.d/vcached
+%dir /etc/vservers
 %attr(0,root,root) %dir /vservers
+%attr(4755,root,root) /usr/sbin/vsh
+%attr(4755,root,root) /bin/vsh
 
 %exclude %_sbindir/newvserver
 %exclude %_mandir/man8/newvserver*
 
-
 %files linuxconf
 %defattr(-,root,root)
 %config(noreplace) /etc/vservers/newvserver.defaults
 %_sbindir/newvserver
 %_mandir/man8/newvserver*
 
-
 %changelog
+* Mon Oct 11 2004 Marc E. Fiuczynski <mef@cs.princeton.edu> 0.1-1.planetlab
+- added vsh
+
+* Wed Aug 11 2004 Mark Huang <mlhuang@cs.princeton.edu> 0.29-1.planetlab
+- initial PlanetLab 3.0 build.
+
 * Thu Mar 18 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de> - 0:0.29.3-0
 - removed '%%doc doc/FAQ.txt' since file does not exist anymore
 
 * Fri Sep 26 2003 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de> - 0:0.23.4-1
 - initial build.
+
diff --git a/util-vserver.spec.in b/util-vserver.spec.in
index 2c9b396..627b248 100644
--- a/util-vserver.spec.in
+++ b/util-vserver.spec.in
@@ -1,13 +1,21 @@
+%define name @PACKAGE@
+%define version @VERSION@
+%define release 6.planetlab%{?date:.%{date}}
+
+Vendor: PlanetLab
+Packager: PlanetLab Central <support@planet-lab.org>
+Distribution: PlanetLab 3.0
+URL: http://cvs.planet-lab.org/cvs/util-vserver
+
 %define __chattr	/usr/bin/chattr
 
 Summary:	Linux virtual server utilities
-Name:		@PACKAGE@
-Version:	@VERSION@
-Release:	0
+Name:		%{name}
+Version:	%{version}
+Release:	%{release}
 Epoch:		0
 Copyright:	GPL
 Group:		System Environment/Base
-URL:		http://savannah.nongnu.org/projects/util-vserver/
 Source0:	http://savannah.nongnu.org/download/util-vserver/stable.pkg/%version/%name-%version.tar.bz2
 Provides:	%name-devel = %epoch:%version-%release
 BuildRoot:	%_tmppath/%name-%version-%release-root
@@ -43,12 +51,17 @@ linuxconf.
 
 %prep
 %setup -q
+aclocal -I m4
+autoconf
+automake --add-missing
+# bootstrap to avoid BuildRequires of kernel-source
+for linux in $RPM_BUILD_DIR/linux-* /lib/modules/`uname -r`/build ; do
+   [[ -d $linux/include ]] && %configure --with-kerneldir=$linux --enable-linuxconf && break
+done
 
 
 %build
-%configure --enable-linuxconf
-%__make %{?_smp_mflags}
-
+make
 
 %install
 rm -rf $RPM_BUILD_ROOT
@@ -60,36 +73,57 @@ test "%_initrddir" = %_sysconfdir/init.d || {
 	mv ${RPM_BUILD_ROOT}%_sysconfdir/init.d/* ${RPM_BUILD_ROOT}%_initrddir/
 }
 
+mkdir -p ${RPM_BUILD_ROOT}/bin
+ln -f ${RPM_BUILD_ROOT}%_sbindir/vsh ${RPM_BUILD_ROOT}/bin/vsh
+
+install -D -m 644 sysv/vcached.logrotate ${RPM_BUILD_ROOT}/etc/logrotate.d/vcached
 
 %clean
 rm -rf $RPM_BUILD_ROOT
 
+%define services vcached vservers
 
-%define v_services	httpd named portmap sendmail smb sshd xinetd
-%post
-/sbin/chkconfig --add vservers
-/sbin/chkconfig --add rebootmgr
+%pre
+# 1 = install, 2 = upgrade/reinstall
+if [ $1 -eq 2 ] ; then
+    for i in %{services} ; do
+	[ "`/sbin/runlevel`" = "unknown" ] || service $i stop || :
+    done
+fi
 
-for i in %v_services; do
-	/sbin/chkconfig --add v_$i
+%post
+# 1 = install, 2 = upgrade/reinstall
+if [ $1 -eq 1 ] ; then
+    for i in %{services} ; do
+	chkconfig --add $i
+	chkconfig $i on
+    done
+fi
+for i in %{services} ; do
+    [ "`/sbin/runlevel`" = "unknown" ] || service $i start
 done
+if [ ! -f /etc/shells ] || ! grep -q '^/bin/vsh$' /etc/shells ; then
+    echo /bin/vsh >> /etc/shells
+fi
 
 %__chattr +t /vservers || :
 
 
-%preun
-test "$1" != 0 || for i in %v_services; do
-	/sbin/chkconfig --del v_$i
-done
-
-test "$1" != 0 || %{_initrddir}/rebootmgr stop &>/dev/null || :
-test "$1" != 0 || /sbin/chkconfig --del rebootmgr
-test "$1" != 0 || /sbin/chkconfig --del vservers
-
-
 %postun
-test "$1" = 0  || %{_initrddir}/rebootmgr condrestart >/dev/null || :
+# 0 = erase, 1 = upgrade
+if [ "$1" = 0 ] ; then
+    perl -i -n -e 'next if /^\/bin\/vsh$/; print' /etc/shells
+fi
 
+%preun
+# 0 = erase, 1 = upgrade
+if [ $1 -eq 0 ] ; then
+    for i in %{services} ; do
+	[ "`/sbin/runlevel`" = "unknown" ] || service $i stop || :
+	chkconfig $i off
+	chkconfig --del $i
+    done
+fi
 
 %files
 %defattr(-,root,root)
@@ -101,22 +135,32 @@ test "$1" = 0  || %{_initrddir}/rebootmgr condrestart >/dev/null || :
 %_mandir/man8/*
 %config %_initrddir/*
 %config(noreplace) /etc/vservers.conf
+%config(noreplace) /etc/vcached.conf
+/etc/logrotate.d/vcached
+%dir /etc/vservers
 %attr(0,root,root) %dir /vservers
+%attr(4755,root,root) /usr/sbin/vsh
+%attr(4755,root,root) /bin/vsh
 
 %exclude %_sbindir/newvserver
 %exclude %_mandir/man8/newvserver*
 
-
 %files linuxconf
 %defattr(-,root,root)
 %config(noreplace) /etc/vservers/newvserver.defaults
 %_sbindir/newvserver
 %_mandir/man8/newvserver*
 
-
 %changelog
+* Mon Oct 11 2004 Marc E. Fiuczynski <mef@cs.princeton.edu> 0.1-1.planetlab
+- added vsh
+
+* Wed Aug 11 2004 Mark Huang <mlhuang@cs.princeton.edu> 0.29-1.planetlab
+- initial PlanetLab 3.0 build.
+
 * Thu Mar 18 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de> - 0:0.29.3-0
 - removed '%%doc doc/FAQ.txt' since file does not exist anymore
 
 * Fri Sep 26 2003 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de> - 0:0.23.4-1
 - initial build.
+