20060322 -- I have started work on a VFS to transparently access file servers via 9P [L1 ], the Plan 9 [L2 ] [L3 ] filesystem protocol. Technically, we support the 9P2000 'version' of 9P.
The code is based on the python 9P implementation by Tim Newsham [L4 ].
The current version of the (work in progress/proof of concept) code can be accessed here: http://plan9.bell-labs.com/sources/contrib/axel/tcl/9pvfs/
Requirements on Tcl version:
Currently the code makes it easy to use 9P as a client in tcl.
Initially the access was readonly, 20060621 support was added to write/create/delete files and create and delete directories.
The intention is to also provide support to easily create (simple) 'synthetic' (virtual) file servers that can be accessed via 9P. That would allow tcl programs to offer access to their resources via 9P.
I'm not sure what the link could be (would be, should be) with something like tclvfs -- ideally there would be one way to define (describe, code, make) a (synthetic) file server in tcl. And then there should be a way to 'ask' any such synthetic file server to talk 9P, either over a given chan, or over a freshly created new chan.
I'll think out loud a bit about creation of synthetic 9P servers at the bottom of this page. Once there has been sufficient thinking I'll start experimenting with code.
To do:
I could probably use some help regarding the naming for dynamically created global variables and maybe also with packaging and/or proper use of namespaces to make the code conform to current tcl standards. I have tried to use namespaces to structure the code, but my experience with namespaces is limited.
Right now there is code to mount a file system over 9P and transparently access it -- code that allows one to use 9P as a client.
The file "main-no-auth.tcl" [L5 ] there mounts the public Plan 9 source repository as user none (without authenticating, like anonymous ftp access) and then accesses it:
source 9pvfs.tcl set fs [socket sources.cs.bell-labs.com 564] fconfigure $fs -translation binary # mount as user none on /tmp vfs::9p::Mount $fs none /tmp puts [glob [file join /tmp *]] set f [open /tmp/plan9/NOTICE r] puts [read $f] close $f cd /tmp/patch puts [glob ./*] cd ../plan9 set f [open LICENSE r] puts [read $f] close $f set f1 [open /tmp/plan9/NOTICE r] set f2 [open LICENSE r] set f3 [open /tmp/plan9/NOTICE r] puts [read $f2] puts [read $f1] puts [read $f3] close $f1 close $f3 close $f2 foreach fn [list /tmp/plan9/NOTICE /tmp / plan9/LICENSE] { file stat $fn X foreach e [array names X] { puts "file stat $fn $e $X($e)" } }
The file"main-auth.tcl" [L6 ] accesses the same repository as a different user, for which authentication is needed. This will fail unless you have an account there. The authentication mechanism uses DES, and hence it requires tclDES.
lappend auto_path tclDES-0.8 source 9pvfs.tcl source p9sk1.tcl set fs [socket sources.cs.bell-labs.com 564] fconfigure $fs -translation binary # mount on /tmp using username name and password secret # using authentication server sources.cs.bell-labs.com # to verify username and password # (have to do this better) vfs::9p::Mount $fs name /tmp sources.cs.bell-labs.com secret puts [glob [file join /tmp *]]
Regarding creation of synthetic 9P file servers: (just thinking out loud)
20060322 -- Initial idea:
It might prove interesting to implement a synthetic 9P file server also as a (user created) tcl channel, using chan create.
Why? Because, essentially, all that 9P needs is a reliable byte stream, and in that respect the chan is as general as we can get. Also, it allows us to access synthetic tcl 9P servers in exactly the same way as we treat real remote 9P file servers that we access over the network (using socket in the examples above).
Open questions:
20060323 -- thinking a bit more:
Probably a synthetic file server should not have a single chan on which it is accessable via 9P, but multiple. That would deal with the first two open questions above.
Assuming that we have a way to create a (9P) synthetic file server, and that we have an 'object' (or command) to access it. Then we should be able to do two things:
The first thing allows us to separately create the 'transport' over which the client accesses the server (for example: the channel created for an incoming connection of a listen socket). The second thing takes care of the simple case where we don't care about the underlying transport but just want to access the synthetic file server.