Index: /package_tags/sipb-xen-console/2/sipb-xen-console/debian/changelog
===================================================================
--- /package_tags/sipb-xen-console/2/sipb-xen-console/debian/changelog	(revision 348)
+++ /package_tags/sipb-xen-console/2/sipb-xen-console/debian/changelog	(revision 348)
@@ -0,0 +1,11 @@
+sipb-xen-console (2) unstable; urgency=low
+
+  * Actually functional release.
+
+ -- SIPB Xen Project <sipb-xen@mit.edu>  Sun, 30 Mar 2008 05:07:43 -0400
+
+sipb-xen-console (1) unstable; urgency=low
+
+  * Initial release.
+
+ -- SIPB Xen Project <sipb-xen@mit.edu>  Sun, 30 Mar 2008 01:08:50 -0400
Index: /package_tags/sipb-xen-console/2/sipb-xen-console/debian/compat
===================================================================
--- /package_tags/sipb-xen-console/2/sipb-xen-console/debian/compat	(revision 348)
+++ /package_tags/sipb-xen-console/2/sipb-xen-console/debian/compat	(revision 348)
@@ -0,0 +1,1 @@
+5
Index: /package_tags/sipb-xen-console/2/sipb-xen-console/debian/control
===================================================================
--- /package_tags/sipb-xen-console/2/sipb-xen-console/debian/control	(revision 348)
+++ /package_tags/sipb-xen-console/2/sipb-xen-console/debian/control	(revision 348)
@@ -0,0 +1,15 @@
+Source: sipb-xen-console
+Section: servers
+Priority: important
+Maintainer: sipb-xen@mit.edu
+Build-Depends: cdbs (>= 0.4.23-1.1), debhelper (>= 5), config-package-dev
+Standards-Version: 3.7.2
+
+Package: sipb-xen-console
+Architecture: all
+Provides: ${diverted-files}
+Conflicts: ${diverted-files}
+Depends: ${shlibs:Depends}, ${misc:Depends}, daemon, fuse-utils, libnss-pgsql1, nscd, openssh-client, openssh-server, python-fuse, sipb-xen-database-common
+Description: SIPB Xen serial console server
+ This package  should be installed on sipb-xen-console
+ It makes sure that necessary tools are available.
Index: /package_tags/sipb-xen-console/2/sipb-xen-console/debian/control.in
===================================================================
--- /package_tags/sipb-xen-console/2/sipb-xen-console/debian/control.in	(revision 348)
+++ /package_tags/sipb-xen-console/2/sipb-xen-console/debian/control.in	(revision 348)
@@ -0,0 +1,15 @@
+Source: sipb-xen-console
+Section: servers
+Priority: important
+Maintainer: sipb-xen@mit.edu
+Build-Depends: @cdbs@
+Standards-Version: 3.7.2
+
+Package: sipb-xen-console
+Architecture: all
+Provides: ${diverted-files}
+Conflicts: ${diverted-files}
+Depends: ${shlibs:Depends}, ${misc:Depends}, daemon, fuse-utils, libnss-pgsql1, nscd, openssh-client, openssh-server, python-fuse, sipb-xen-database-common
+Description: SIPB Xen serial console server
+ This package  should be installed on sipb-xen-console
+ It makes sure that necessary tools are available.
Index: /package_tags/sipb-xen-console/2/sipb-xen-console/debian/copyright
===================================================================
--- /package_tags/sipb-xen-console/2/sipb-xen-console/debian/copyright	(revision 348)
+++ /package_tags/sipb-xen-console/2/sipb-xen-console/debian/copyright	(revision 348)
@@ -0,0 +1,3 @@
+This package was created for internal use of the SIPB Xen Project of
+the MIT Student Information Processing Board.  Ask sipb-xen@mit.edu if
+you have questions about redistribution.
Index: /package_tags/sipb-xen-console/2/sipb-xen-console/debian/rules
===================================================================
--- /package_tags/sipb-xen-console/2/sipb-xen-console/debian/rules	(revision 348)
+++ /package_tags/sipb-xen-console/2/sipb-xen-console/debian/rules	(revision 348)
@@ -0,0 +1,12 @@
+#!/usr/bin/make -f
+
+DEB_AUTO_UPDATE_DEBIAN_CONTROL = 1
+DEB_DIVERT_EXTENSION = .sipb-xen
+DEB_DIVERT_FILES_sipb-xen-console += \
+	/etc/nscd.conf \
+	/etc/nsswitch.conf \
+	/etc/pam.d/ssh \
+	/etc/ssh/ssh_config
+
+include /usr/share/cdbs/1/rules/debhelper.mk
+include /usr/share/cdbs/1/rules/replace-files.mk
Index: /package_tags/sipb-xen-console/2/sipb-xen-console/debian/sipb-xen-console.init
===================================================================
--- /package_tags/sipb-xen-console/2/sipb-xen-console/debian/sipb-xen-console.init	(revision 348)
+++ /package_tags/sipb-xen-console/2/sipb-xen-console/debian/sipb-xen-console.init	(revision 348)
@@ -0,0 +1,125 @@
+#! /bin/sh
+### BEGIN INIT INFO
+# Provides:          sipb-xen-console
+# Required-Start:    $local_fs $remote_fs
+# Required-Stop:     $local_fs $remote_fs
+# Default-Start:     2 3 4 5
+# Default-Stop:      0 1 6
+# Short-Description: sipb-xen Console Server homedir filesystem
+# Description:       
+### END INIT INFO
+
+# Author: SIPB Xen Project <sipb-xen@mit.edu>
+
+# Do NOT "set -e"
+
+# PATH should only include /usr/* if it runs after the mountnfs.sh script
+PATH=/sbin:/usr/sbin:/bin:/usr/bin
+DESC="The sipb-xen console server homedir filesystem"
+NAME=sipb-xen-console
+DAEMON=/usr/bin/sipb-xen-consolefs
+DAEMON_ARGS="/consolefs"
+PIDFILE=/var/run/$NAME.pid
+SCRIPTNAME=/etc/init.d/$NAME
+
+# Exit if the package is not installed
+[ -x "$DAEMON" ] || exit 0
+
+# Read configuration variable file if it is present
+[ -r /etc/default/$NAME ] && . /etc/default/$NAME
+
+# Load the VERBOSE setting and other rcS variables
+. /lib/init/vars.sh
+
+# Define LSB log_* functions.
+# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
+. /lib/lsb/init-functions
+
+#
+# Function that starts the daemon/service
+#
+do_start()
+{
+	# Return
+	#   0 if daemon has been started
+	#   1 if daemon was already running
+	#   2 if daemon could not be started
+	daemon --running -n $NAME && return 1
+	daemon -r -O daemon.info -E daemon.err -n $NAME -U $DAEMON $DAEMON_ARGS || return 2
+}
+
+#
+# Function that stops the daemon/service
+#
+do_stop()
+{
+	# Return
+	#   0 if daemon has been stopped
+	#   1 if daemon was already stopped
+	#   2 if daemon could not be stopped
+	#   other if a failure occurred
+	daemon --stop -n $NAME
+	RETVAL="$?"
+	[ "$RETVAL" = 2 ] && return 2
+	# Many daemons don't delete their pidfiles when they exit.
+	rm -f $PIDFILE
+	umount "$DAEMON_ARGS"
+	return "$RETVAL"
+}
+
+case "$1" in
+  start)
+	[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
+	do_start
+	case "$?" in
+		0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
+		2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
+	esac
+	;;
+  stop)
+	[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
+	do_stop
+	case "$?" in
+		0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
+		2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
+	esac
+	;;
+  #reload|force-reload)
+	#
+	# If do_reload() is not implemented then leave this commented out
+	# and leave 'force-reload' as an alias for 'restart'.
+	#
+	#log_daemon_msg "Reloading $DESC" "$NAME"
+	#do_reload
+	#log_end_msg $?
+	#;;
+  restart|force-reload)
+	#
+	# If the "reload" option is implemented then remove the
+	# 'force-reload' alias
+	#
+	log_daemon_msg "Restarting $DESC" "$NAME"
+	do_stop
+	case "$?" in
+	  0|1)
+		do_start
+		case "$?" in
+			0) log_end_msg 0 ;;
+			1) log_end_msg 1 ;; # Old process is still running
+			*) log_end_msg 1 ;; # Failed to start
+		esac
+		;;
+	  *)
+	  	# Failed to stop
+		log_end_msg 1
+		;;
+	esac
+	;;
+  *)
+	#echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
+	echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
+	exit 3
+	;;
+esac
+
+:
Index: /package_tags/sipb-xen-console/2/sipb-xen-console/debian/sipb-xen-console.install
===================================================================
--- /package_tags/sipb-xen-console/2/sipb-xen-console/debian/sipb-xen-console.install	(revision 348)
+++ /package_tags/sipb-xen-console/2/sipb-xen-console/debian/sipb-xen-console.install	(revision 348)
@@ -0,0 +1,1 @@
+files/* .
Index: /package_tags/sipb-xen-console/2/sipb-xen-console/files/etc/nscd.conf.sipb-xen
===================================================================
--- /package_tags/sipb-xen-console/2/sipb-xen-console/files/etc/nscd.conf.sipb-xen	(revision 348)
+++ /package_tags/sipb-xen-console/2/sipb-xen-console/files/etc/nscd.conf.sipb-xen	(revision 348)
@@ -0,0 +1,67 @@
+#
+# /etc/nscd.conf
+#
+# An example Name Service Cache config file.  This file is needed by nscd.
+#
+# Legal entries are:
+#
+#	logfile			<file>
+#	debug-level		<level>
+#	threads			<initial #threads to use>
+#	max-threads		<maximum #threads to use>
+#	server-user             <user to run server as instead of root>
+#		server-user is ignored if nscd is started with -S parameters
+#       stat-user               <user who is allowed to request statistics>
+#	reload-count		unlimited|<number>
+#	paranoia		<yes|no>
+#	restart-interval	<time in seconds>
+#
+#       enable-cache		<service> <yes|no>
+#	positive-time-to-live	<service> <time in seconds>
+#	negative-time-to-live   <service> <time in seconds>
+#       suggested-size		<service> <prime number>
+#	check-files		<service> <yes|no>
+#	persistent		<service> <yes|no>
+#	shared			<service> <yes|no>
+#
+# Currently supported cache names (services): passwd, group, hosts
+#
+
+
+#	logfile			/var/log/nscd.log
+#	threads			6
+#	max-threads		128
+#	server-user		nobody
+#	stat-user		somebody
+	debug-level		0
+#	reload-count		5
+	paranoia		no
+#	restart-interval	3600
+
+	enable-cache		passwd		yes
+	positive-time-to-live	passwd		600
+#	negative-time-to-live	passwd		20
+	negative-time-to-live	passwd		3
+	suggested-size		passwd		211
+	check-files		passwd		yes
+#	persistent		passwd		yes
+	persistent		passwd		no
+	shared			passwd		yes
+
+	enable-cache		group		yes
+	positive-time-to-live	group		3600
+#	negative-time-to-live	group		60
+	negative-time-to-live	group		3
+	suggested-size		group		211
+	check-files		group		yes
+#	persistent		group		yes
+	persistent		group		no
+	shared			group		yes
+
+	enable-cache		hosts		yes
+	positive-time-to-live	hosts		3600
+	negative-time-to-live	hosts		20
+	suggested-size		hosts		211
+	check-files		hosts		yes
+	persistent		hosts		yes
+	shared			hosts		yes
Index: /package_tags/sipb-xen-console/2/sipb-xen-console/files/etc/nss-pgsql.conf
===================================================================
--- /package_tags/sipb-xen-console/2/sipb-xen-console/files/etc/nss-pgsql.conf	(revision 348)
+++ /package_tags/sipb-xen-console/2/sipb-xen-console/files/etc/nss-pgsql.conf	(revision 348)
@@ -0,0 +1,18 @@
+# example configfile for PostgreSQL NSS module
+
+# these are entries as used with the BOFHMS tool (sf.net/projects/bofhms)
+host		= sipb-xen-dev
+port		= 5432
+database	= sipb_xen
+login		= sipb-xen
+
+querypasswd = SELECT name, NULL, machine_id + 1000 as uid, machine_id + 1000 as gid, '', '/consolefs/'|| name, '/usr/bin/sipb-xen-consolesh' FROM machines
+querygroup = SELECT name, NULL, machine_id + 1000 as gid FROM machines
+querymembers = SELECT name FROM machines WHERE 1000 + machine_id = %d
+queryids = SELECT 1000 + machine_id AS gid FROM machines LIMIT 0
+
+passwd_name = name
+passwd_uid = 1000 + machine_id
+
+group_name = name
+group_gid = 1000 + machine_id
Index: /package_tags/sipb-xen-console/2/sipb-xen-console/files/etc/nsswitch.conf.sipb-xen
===================================================================
--- /package_tags/sipb-xen-console/2/sipb-xen-console/files/etc/nsswitch.conf.sipb-xen	(revision 348)
+++ /package_tags/sipb-xen-console/2/sipb-xen-console/files/etc/nsswitch.conf.sipb-xen	(revision 348)
@@ -0,0 +1,19 @@
+# /etc/nsswitch.conf
+#
+# Example configuration of GNU Name Service Switch functionality.
+# If you have the `glibc-doc-reference' and `info' packages installed, try:
+# `info libc "Name Service Switch"' for information about this file.
+
+passwd:         compat pgsql
+group:          compat pgsql
+shadow:         compat
+
+hosts:          files dns
+networks:       files
+
+protocols:      db files
+services:       db files
+ethers:         db files
+rpc:            db files
+
+netgroup:       nis
Index: /package_tags/sipb-xen-console/2/sipb-xen-console/files/etc/pam.d/ssh.sipb-xen
===================================================================
--- /package_tags/sipb-xen-console/2/sipb-xen-console/files/etc/pam.d/ssh.sipb-xen	(revision 348)
+++ /package_tags/sipb-xen-console/2/sipb-xen-console/files/etc/pam.d/ssh.sipb-xen	(revision 348)
@@ -0,0 +1,39 @@
+# PAM configuration for the Secure Shell service
+
+# Read environment variables from /etc/environment and
+# /etc/security/pam_env.conf.
+auth       required     pam_env.so # [1]
+# In Debian 4.0 (etch), locale-related environment variables were moved to
+# /etc/default/locale, so read that as well.
+auth       required     pam_env.so envfile=/etc/default/locale
+
+# Standard Un*x authentication.
+@include common-auth
+
+# Disallow non-root logins when /etc/nologin exists.
+account    required     pam_nologin.so
+
+# Uncomment and edit /etc/security/access.conf if you need to set complex
+# access limits that are hard to express in sshd_config.
+# account  required     pam_access.so
+
+# Standard Un*x authorization.
+@include common-account
+
+# Standard Un*x session setup and teardown.
+@include common-session
+
+# Print the message of the day upon successful login.
+#session    optional     pam_motd.so # [1]
+
+# Print the status of the user's mailbox upon successful login.
+session    optional     pam_mail.so standard noenv # [1]
+
+# Set up user limits from /etc/security/limits.conf.
+session    required     pam_limits.so
+
+# Set up SELinux capabilities (need modified pam)
+# session  required     pam_selinux.so multiple
+
+# Standard Un*x password updating.
+@include common-password
Index: /package_tags/sipb-xen-console/2/sipb-xen-console/files/etc/ssh/ssh_config.sipb-xen
===================================================================
--- /package_tags/sipb-xen-console/2/sipb-xen-console/files/etc/ssh/ssh_config.sipb-xen	(revision 348)
+++ /package_tags/sipb-xen-console/2/sipb-xen-console/files/etc/ssh/ssh_config.sipb-xen	(revision 348)
@@ -0,0 +1,47 @@
+
+# This is the ssh client system-wide configuration file.  See
+# ssh_config(5) for more information.  This file provides defaults for
+# users, and the values can be changed in per-user configuration files
+# or on the command line.
+
+# Configuration data is parsed as follows:
+#  1. command line options
+#  2. user-specific file
+#  3. system-wide file
+# Any configuration value is only changed the first time it is set.
+# Thus, host-specific definitions should be at the beginning of the
+# configuration file, and defaults at the end.
+
+# Site-wide defaults for some commonly used options.  For a comprehensive
+# list of available options, their meanings and defaults, please see the
+# ssh_config(5) man page.
+
+Host *
+   SendEnv VM_NAME
+#   ForwardAgent no
+#   ForwardX11 no
+#   ForwardX11Trusted yes
+#   RhostsRSAAuthentication no
+#   RSAAuthentication yes
+#   PasswordAuthentication yes
+#   HostbasedAuthentication no
+#   BatchMode no
+#   CheckHostIP yes
+#   AddressFamily any
+#   ConnectTimeout 0
+#   StrictHostKeyChecking ask
+#   IdentityFile ~/.ssh/identity
+#   IdentityFile ~/.ssh/id_rsa
+#   IdentityFile ~/.ssh/id_dsa
+#   Port 22
+#   Protocol 2,1
+#   Cipher 3des
+#   Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc
+#   EscapeChar ~
+#   Tunnel no
+#   TunnelDevice any:any
+#   PermitLocalCommand no
+    SendEnv LANG LC_*
+    HashKnownHosts yes
+    GSSAPIAuthentication yes
+    GSSAPIDelegateCredentials no
Index: /package_tags/sipb-xen-console/2/sipb-xen-console/files/etc/ssh/ssh_known_hosts
===================================================================
--- /package_tags/sipb-xen-console/2/sipb-xen-console/files/etc/ssh/ssh_known_hosts	(revision 348)
+++ /package_tags/sipb-xen-console/2/sipb-xen-console/files/etc/ssh/ssh_known_hosts	(revision 348)
@@ -0,0 +1,3 @@
+|1|CoekhjakJDYiibQ38vZna+XKwCg=|Ts2GavZxl8KVEl++tnJnjqfn84s= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAsoOOazVHn04z6s+kQnoFcw9fv7dGB9s/9H1QygYW9QAbvklWx0q4J8KGTATXCFwjooLNqjHYONOQ8x0h1fZPDmhdoHk24wH/EBUAAyhtrwTMpsgfqZwG7yuRpcbO382F3wRv6CIRYZ6hyIlm0Zt3680mO/u7l2wAFoMTyYwSdZ8Gl9p5Ay750TFCZoEI/Z4EQY5lGPHrHIXN+uo0Yus//AmWIzY9y3TSKabHz77rPGIzJc8Y4XjDqA7LzXCY+KGw2Of059AseVHNTCMo6KzVIKgdZoRBtiY7fD1l7ystgKL6lGJr4C1UyWoM41EVkDqsRJZ70C4Elcr1x/MrQFLEgQ==
+|1|SFl+Ci6EXZcVvxvxDm4Cf85nGho=|InwYz5wWUf/NRbBQRa/TO3Lm2uQ= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAsoOOazVHn04z6s+kQnoFcw9fv7dGB9s/9H1QygYW9QAbvklWx0q4J8KGTATXCFwjooLNqjHYONOQ8x0h1fZPDmhdoHk24wH/EBUAAyhtrwTMpsgfqZwG7yuRpcbO382F3wRv6CIRYZ6hyIlm0Zt3680mO/u7l2wAFoMTyYwSdZ8Gl9p5Ay750TFCZoEI/Z4EQY5lGPHrHIXN+uo0Yus//AmWIzY9y3TSKabHz77rPGIzJc8Y4XjDqA7LzXCY+KGw2Of059AseVHNTCMo6KzVIKgdZoRBtiY7fD1l7ystgKL6lGJr4C1UyWoM41EVkDqsRJZ70C4Elcr1x/MrQFLEgQ==
+|1|52lp5FTRtu4Fyk8GvC3mH2idB+0=|fGJ+LwWltfUP9kC1fiMfJO5XrVk= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAsoOOazVHn04z6s+kQnoFcw9fv7dGB9s/9H1QygYW9QAbvklWx0q4J8KGTATXCFwjooLNqjHYONOQ8x0h1fZPDmhdoHk24wH/EBUAAyhtrwTMpsgfqZwG7yuRpcbO382F3wRv6CIRYZ6hyIlm0Zt3680mO/u7l2wAFoMTyYwSdZ8Gl9p5Ay750TFCZoEI/Z4EQY5lGPHrHIXN+uo0Yus//AmWIzY9y3TSKabHz77rPGIzJc8Y4XjDqA7LzXCY+KGw2Of059AseVHNTCMo6KzVIKgdZoRBtiY7fD1l7ystgKL6lGJr4C1UyWoM41EVkDqsRJZ70C4Elcr1x/MrQFLEgQ==
Index: /package_tags/sipb-xen-console/2/sipb-xen-console/files/usr/bin/sipb-xen-consolefs
===================================================================
--- /package_tags/sipb-xen-console/2/sipb-xen-console/files/usr/bin/sipb-xen-consolefs	(revision 348)
+++ /package_tags/sipb-xen-console/2/sipb-xen-console/files/usr/bin/sipb-xen-consolefs	(revision 348)
@@ -0,0 +1,181 @@
+#!/usr/bin/python
+
+import fuse
+from fuse import Fuse
+
+from time import time
+
+import stat	# for file properties
+import os	  # for filesystem modes (O_RDONLY, etc)
+import errno   # for error number codes (ENOENT, etc)
+			   # - note: these must be returned as negatives
+
+import sipb_xen_database
+
+fuse.fuse_python_api = (0, 2)
+
+realpath = "/home/machines/"
+
+def dirFromList(list):
+	"""
+	Return a properly formatted list of items suitable to a directory listing.
+	['a', 'b', 'c'] => [('a', 0), ('b', 0), ('c', 0)]
+	"""
+	return [(x, 0) for x in list]
+
+def getDepth(path):
+	"""
+	Return the depth of a given path, zero-based from root ('/')
+	"""
+	if path == '/':
+		return 0
+	else:
+		return path.count('/')
+
+def getParts(path):
+	"""
+	Return the slash-separated parts of a given path as a list
+	"""
+	if path == '/':
+		return ['/']
+	else:
+		return path[1:].split('/')
+
+class MyStat:
+	def __init__(self):
+		self.st_mode = 0
+		self.st_ino = 0
+		self.st_dev = 0
+		self.st_nlink = 0
+		self.st_uid = 0
+		self.st_gid = 0
+		self.st_size = 0
+		self.st_atime = 0
+		self.st_mtime = 0
+		self.st_ctime = 0
+	
+	def toTuple(self):
+		return (self.st_mode, self.st_ino, self.st_dev, self.st_nlink, self.st_uid, self.st_gid, self.st_size, self.st_atime, self.st_mtime, self.st_ctime)
+
+class ConsoleFS(Fuse):
+	"""
+	"""
+	
+	def __init__(self, *args, **kw):
+		Fuse.__init__(self, *args, **kw)
+		self.lasttime = time()
+		self.allow_other = 1
+		print 'Init complete.'
+	
+	def mirrorPath(self, path):
+		return realpath + "/".join(getParts(path)[1:])
+	
+	def getMachines(self):
+		if time() - self.lasttime > 15:
+			self.lasttime = time()
+			sipb_xen_database.clear_cache()
+		return [machine.name for machine in sipb_xen_database.Machine.select()]
+	
+	def getUid(self, machine_name):
+		return sipb_xen_database.Machine.get_by(name=machine_name).machine_id + 1000
+	
+	def getK5login(self, machine_name):
+		machine = sipb_xen_database.Machine.get_by(name=machine_name)
+		users = [acl.user for acl in machine.acl]
+		return "\n".join(map(self.userToPrinc, users) + [''])
+	
+	def userToPrinc(self, user):
+		if '@' in user:
+			(princ, realm) = user.split('@')
+		else:
+			princ = user
+			realm = "ATHENA.MIT.EDU"
+		
+		return princ.replace('.', '/') + realm
+	
+	def getattr(self, path):
+		"""
+		- st_mode (protection bits)
+		- st_ino (inode number)
+		- st_dev (device)
+		- st_nlink (number of hard links)
+		- st_uid (user ID of owner)
+		- st_gid (group ID of owner)
+		- st_size (size of file, in bytes)
+		- st_atime (time of most recent access)
+		- st_mtime (time of most recent content modification)
+		- st_ctime (platform dependent; time of most recent metadata change on Unix,
+					or the time of creation on Windows).
+		"""
+		
+		print "*** getattr: " + path
+		
+		depth = getDepth(path)
+		parts = getParts(path)
+		
+		st = MyStat()
+		if path == '/':
+			st.st_mode = stat.S_IFDIR | 0755
+			st.st_nlink = 2
+		elif depth == 1:
+			if parts[-1] in self.getMachines():
+				st.st_mode = stat.S_IFDIR | 0755
+				st.st_nlink = 2
+				st.st_uid = st.st_gid = self.getUid(parts[0])
+			else:
+				return -errno.ENOENT
+		elif depth == 2 and parts[-1] == '.k5login':
+			st.st_mode = stat.S_IFREG | 0444
+			st.st_nlink = 1
+			st.st_size = len(self.getK5login(parts[0]))
+			st.st_uid = st.st_gid = self.getUid(parts[0])
+		else:
+			stats = list(os.lstat(self.mirrorPath(path)))
+			stats[4:6] = [self.getUid(parts[0])] * 2
+			return tuple(stats)
+		return st.toTuple()
+	
+	def readdir(self, path, offset):
+		print '*** readdir', path, offset
+		for (value, zero) in self.getdir(path):
+			yield fuse.Direntry(value)
+	
+	def getdir(self, path):
+		print '*** getdir', path
+		if path == '/':
+			contents = ['.', '..']+self.getMachines()
+		elif getDepth(path) == 1:
+			contents = set(os.listdir(self.mirrorPath(path)) + ['.k5login', '.', '..'])
+		else:
+			contents = os.listdir(self.mirrorPath(path)) + ['.', '..']
+		return [(i, 0) for i in contents]
+	
+	def read ( self, path, length, offset ):
+		print '*** read', path, length, offset
+		
+		parts = getParts(path)
+		
+		if getDepth(path) < 2:
+			return -errno.ENOENT
+		elif parts[1:] == ['.k5login']:
+			if parts[0] not in self.getMachines():
+				return -errno.ENOENT
+			else:
+				return self.getK5login(parts[0])[offset:length + offset]
+		else:
+			fname = self.mirrorPath(path)
+			if not os.path.isfile(fname):
+				return -errno.ENOENT
+			else:
+				f = open(fname)
+				f.seek(offset)
+				return f.read(length)
+
+if __name__ == '__main__':
+	sipb_xen_database.connect('postgres://sipb-xen@sipb-xen-dev.mit.edu/sipb_xen')
+	usage="""
+ConsoleFS [mount_path]
+"""
+	server = ConsoleFS()
+	server.flags = 0
+	server.main()
Index: /package_tags/sipb-xen-console/2/sipb-xen-console/files/usr/bin/sipb-xen-consolesh
===================================================================
--- /package_tags/sipb-xen-console/2/sipb-xen-console/files/usr/bin/sipb-xen-consolesh	(revision 348)
+++ /package_tags/sipb-xen-console/2/sipb-xen-console/files/usr/bin/sipb-xen-consolesh	(revision 348)
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+export VM_NAME="d_$USER"
+ssh console@black-mesa
