Subversion Repositories planix.SVN

Rev

Blame | Last modification | View Log | RSS feed

#!/bin/rc

# Serve Unix u9fs over SSH
#
# Basically, try each of the following until you find one that works:
#
#       srvssh unix
#       srvssh -r unix
#       srvssh -R unix
#       srvssh -r -s unix
#       srvssh -R -s unix
#
# and then never look back.  Note that "srvssh unix" should always
# work.  It's just that if you're talking with certain sshd's, you'll get
# hit by Nagle's algorithm and need to explore the other flags.

# When using ssh to start u9fs, the only way to turn off
# Nagle's algorithm (which kills the performance of RPC-based
# protocols like 9P) is to allocate a pseudo-terminal.  The
# command ssh -Rmp attempts to allocate a pseudo-terminal and
# then put it in a transparent mode.  Especially when
# connected to older SSH daemons, the connection ends up not
# quite transparent.  To get around this, we explicity set the tty
# mode on the command line as well.  The hope is that -Rmp makes
# the connection transparent enough for the Tversion, and the stty
# command will do the rest.  If -Rmp doesn't make the connection
# transparent enough for the Tversion (but the stty commands do 
# make the connection fully transparent) then add "-s 5" to the srv
# command to tell it to wait 5 seconds before sending the Tversion.
# That should be enough time for the stty to take effect.

rfork e

fn usage {
        echo 'usage: srvssh [-R] [-r] [-s] [-u u9fspath] system [srvname [mtpt]]' >[1=2]
        exit usage
}

rawhack=''
sleephack=()
u9fspath=u9fs
rawflags=''

while(~ $1 -*){
        switch($1){
        case -r
                rawflags='-Rmp'
                shift
        case -R
                rawflags='-Rmp'
                rawhack=('stty raw -echo '';''')
                shift
        case -s
                sleephack=(-s 5)
                shift
        case -u
                shift
                u9fspath=$1
                shift
        case -u*
                u9fspath=`{echo $1 | sed s/-u//}
                shift
        case *
                usage
        }
}

if(! ~ $#* 1 2 3)
        usage

switch($#*){
case 1
        srv=$1
        mtpt=/n/$1
case 2
        srv=$2
        mtpt=/n/$1
case 3
        srv=$2
        mtpt=$3
}

x=(srv $sleephack -e \
        'ssh '$rawflags' '$1' '$rawhack' '$u9fspath' -na none -u ''$''USER -l ''$''HOME/u9fs.log' \
        $srv $mtpt)
$x

# Sometimes /srv/whatever can be a closed pipe, in which case
# srv will have been killed for writing to it, without a chance to
# defend itself.  Rerun it in this case.

ss=$status
if(~ $ss *'write on closed pipe'*){
        rm -f /srv/$srv
        $x
        ss=$status
}

if(! ~ $ss '')
        echo srvssh: $ss >[1=2]
exit $ss