From: Justin Gullingsrud (justin_at_ks.uiuc.edu)
Date: Wed Feb 12 2003 - 16:46:36 CST

Note that my suggestion won't get text that has 'Info:' or 'Error', since
this text is written directly by VMD to stdout, not to the Tcl interpreter.
It only gives you the result of executing Tcl commands. I don't know of any
way of intercepting text sent to stdout.

Cheers,
Justin

On Wed, Feb 12, 2003 at 04:43:18PM -0600, Justin Gullingsrud wrote:
> Oliver,
>
> I think all you have you do is replace "eval $line" in your script
> with the following:
>
> set rc [catch $line result]
> if { $rc } {
> puts $sock "Error executing comand '$line': \n$result"
> } else {
> puts $sock $result
> }
> This should also fix the problem with erroneous commands causing the server
> to fail. What's probably happening is that Tcl is shutting down the socket
> when an uncaught error occurs during execution of the read handler.
>
> Cheers,
> Justin
>
> On Wed, Feb 12, 2003 at 10:10:04PM +0000, Oliver Beckstein wrote:
> > Hello,
> >
> > I am looking for help with a tcl script (based on vmdcollab) that
> > turns vmd into a remote-controlled display server. remote_ctl.tcl is
> > appended at the end. (I am sorry if this is too much clutter for the
> > list).
> >
> > At the moment connecting works (telnet localhost 5555) and so does
> > sending commands (eg 'draw sphere {1 0 0} radius .3 resolution
> > 24'). My main problem is that I don't know how to tell tcl that I want
> > VMD's stdout redirected to the socket so that my remote application
> > (telnet in this case) can read it. I have tried a fileevent handler on
> > stdout but this did not work (it is called perpetually and I still
> > cannot access the actual VMD output).
> >
> > A minor problem is that a wrong command seems to block the connection,
> > that is, no commands after the first wrong one will have any effect.
> >
> > And (as is probably obvious from the code): I am a complete newbie at
> > tcl so any help or comments are very much appreciated.
> >
> > Thanks,
> > Oliver
> >
> > #------------------------------------------------------------------
> > # $Id: remote_ctl.tcl,v 1.6 2003/02/12 21:33:11 oliver Exp $
> > # based on bounce.tcl and vmdcollab.tcl
> > # from http://www.ks.uiuc.edu/Research/vmd/script_library/scripts/vmdcollab/
> > #
> > # start this in VMD and send commands to the listening port to have VMD
> > # execute them remotely
> > # (also see http://www.tcl.tk/scripting/netserver.html)
> > #
> > # Usage: vmd -e remote_ctl.tcl
> > # or vmd> source remote_ctl.tcl
> > #
> > # Security: we only allow connections from localhost (see acpt)
> > #
> > # Bugs:
> > # * once a wrong command was sent, the connection appears
> > # to 'block' and does not accept correct commands later
> > # * does not write result back to socket (one way connection...) so
> > # there is no way to inquire objects in vmd
> >
> > namespace eval remote_ctl {
> > variable main
> > variable clients
> > variable default_vmd_port
> >
> > set default_vmd_port 5555
> >
> > # I am too dumb to set the default value for port from
> > # $default_vmd_port so I put 5555 in there literally
> > proc start { {port 5555} } {
> > variable main
> > set main [socket -server remote_ctl::acpt $port]
> > putlog "Listening on port $port"
> > }
> >
> > proc acpt { sock addr port } {
> > variable clients
> > if {[string compare $addr "127.0.0.1"] != 0} {
> > putlog "Unauthorized connection attempt from $addr port $port"
> > close $sock
> > return
> > }
> > putlog "Accept $sock from $addr port $port"
> > set clients($sock) 1
> > fconfigure $sock -buffering line
> > fileevent $sock readable [list remote_ctl::recv $sock]
> > }
> >
> > proc recv { sock } {
> > variable main
> > variable clients
> > if { [eof $sock] || [catch {gets $sock line}]} {
> > # end of file or abnormal connection drop:
> > # shut down this connection
> > close $sock
> > putlog "Closing $sock"
> > unset clients($sock)
> > } else {
> > if {[string compare $line "quit"] == 0} {
> > # prevent new connections
> > # existing connections stay open
> > # No -- Bug(?): 'quit' closes VMD...
> > putlog "Disallowing incoming connections by request of $sock"
> > close $main
> > }
> > # execute the received commands
> > # should check for runtime errors which otherwise leave the connection
> > # in an unusable state
> > eval $line
> > }
> > }
> >
> >
> > ###### would like the last line from stdout in line ###########
> > # (or any working solution....)
> > proc send { sock line} {
> > variable clients
> > # send reply to connecting client
> > putlog "send '$line' to $sock"
> > puts $sock $line
> > }
> >
> >
> > proc putlog { text } {
> > puts $text
> > return
> > }
> > }
> >
> >
> > # assuming that loading this file means that we actually want to run
> > # the server, we just start it:
> > remote_ctl::putlog "Starting remote_ctl server in vmd: connect with something like"
> > remote_ctl::putlog "telnet localhost 5555"
> >
> > remote_ctl::start
> >
> > #-------------------------------------------------------------
> >
> > --
> > Oliver Beckstein * oliver_at_bioch.ox.ac.uk
> > http://indigo1.biop.ox.ac.uk/oliver/
>
> --
>
> Justin Gullingsrud 3111 Beckman Institute 217-244-8946
> I been dropping the new science, and I be kicking the new knowledge,
> and I'm seeing to a degree that you can't get in college. -- b.boys

-- 
  Justin Gullingsrud        3111 Beckman Institute        217-244-8946
  I been dropping the new science, and I be kicking the new knowledge,
  and I'm seeing to a degree that you can't get in college.  -- b.boys