2008-03-18 Paolo Bonzini * scripts/Remote.st: Implement ssh connections. * gst-tool.c: Add --login to gst-remote. diff --git a/gst-tool.c b/gst-tool.c index 5f0dea2..969dd76 100644 --- a/gst-tool.c +++ b/gst-tool.c @@ -131,8 +131,8 @@ struct tool tools[] = { { "gst-remote", "scripts/Remote.st", "-h|--help --version --daemon --server -p|--port: -f|--file: -e|--eval: \ - --package: --start: --stop: --pid --kill --snapshot:: -I|--image-file: \ - --kernel-directory:", + -l|--login: --package: --start: --stop: --pid --kill --snapshot:: \ + -I|--image-file: --kernel-directory:", NULL }, { NULL, NULL, NULL, NULL } diff --git a/scripts/Remote.st b/scripts/Remote.st index e6c488e..6313b48 100644 --- a/scripts/Remote.st +++ b/scripts/Remote.st @@ -67,15 +67,16 @@ TextCollector subclass: MultiplexingTextCollector [ ] ] -| helpString commands server port host | +| helpString commands server port host login | commands := OrderedCollection new. server := false. port := 12345. host := nil. +login := nil. helpString := 'Usage: - gst-remote [ flag ... ] host + gst-remote [ flag ... ] [user@]host Options: --daemon start background server @@ -83,6 +84,7 @@ Options: -p --port=PORT connect/listen on given port (default 12345) -f --file=FILE file in FILE -e --eval=CODE evaluate CODE + -l --login=USER use remote ssh connection --kill kill daemon --snapshot[=FILE] save image --package=PACKAGE load package @@ -91,13 +93,17 @@ Options: --pid print daemon pid -h --help show this message --version print version information and exit + +If a remote login name is given, gst-remote will use the SSH environment +variable (if present) to launch commands remotely. Netcat (nc) should be +available in the PATH of the remote machine. '. "Parse the command-line arguments." -Smalltalk +[Smalltalk arguments: '-h|--help --version --daemon --server -p|--port: -f|--file: -e|--eval: --pid --kill --snapshot:: --start: --stop: - --package: -I|--image: --kernel-directory:' + -l|--login: --package: -I|--image: --kernel-directory:' do: [ :opt :arg | opt = 'help' ifTrue: [ @@ -108,6 +114,10 @@ Smalltalk ('gst-remote - %1' % {Smalltalk version}) displayNl. ObjectMemory quit: 0 ]. + opt = 'login' ifTrue: [ + login isNil ifFalse: [ self error: 'multiple logins are invalid' ]. + login := arg ]. + opt = 'daemon' ifTrue: [ server := true ]. @@ -161,12 +171,19 @@ Smalltalk (Directory append: arg to: Directory working) storeString ] ]. opt isNil ifTrue: [ - host isNil ifFalse: [ - helpString displayOn: stderr. - ObjectMemory quit: 1 ]. - host := arg ] ] - - ifError: [ + host isNil ifFalse: [ self error: 'multiple hosts are invalid' ]. + (arg includes: $@) + ifFalse: [ host := arg ] + ifTrue: [ + login isNil ifFalse: [ self error: 'multiple logins are invalid' ]. + login := arg copyUpTo: $@. + host := arg copyAfter: $@ ] ]. + ] +] + on: Error do: [ :ex | + ('gst-remote: ', ex messageText, ' +') displayOn: stderr. + stderr flush. helpString displayOn: stderr. ObjectMemory quit: 1 ]. @@ -217,9 +234,16 @@ server ifTrue: [ [ commands isEmpty ifFalse: [ - s := host isNil - ifTrue: [ TCP.Socket remote: TCP.IPAddress anyLocalAddress port: port ] - ifFalse: [ TCP.Socket remote: host port: port ]. + s := (login isNil or: [ host isNil ]) + ifTrue: [ + host isNil ifTrue: [ host := TCP.IPAddress anyLocalAddress ]. + TCP.Socket remote: host port: port ] + ifFalse: [ + FileStream + popen: '%1 %2@%3 nc localhost %4' % { + (Smalltalk getenv: 'SSH') ifNil: [ 'ssh' ]. + login. host. port} + dir: 'r+' ]. commands do: [ :each | "Using #readStream makes it work both for Strings and Files."