newguy: Check out the Changelog (in particular v7.0 and the new 7.2.0) for information on Virtual_Dirs. An early example can be found if you look at source/nxSearch.itcl which is a simple test script I wrote to return search results from the nxTools dupedb. The ioVirtual call to fill in the directory listing is documented in the doc/iTCL.txt file.
Here's a newer example I was using to test with that just mirrors a VFS dir on the server as a pure virtual dir. I know, virtual this virtual that... I wasn't planning on releasing this yet so it's not documented and it contains whatever I was playing with at the time I was testing, but it may help you. In particular note that you can get the files/dirs to display in the listing from anywhere including a database like in the nxSearch example, but I just used another dir so I could compare them visually to see if things were working correctly...
Code:
# NOTE: <>'s are invalid in real filenames so useful to return them for purely
# fake subdirectories because the server won't try to resolve them and thus
# we save a lot of overhead.
set mDir "test2"
set vDir "vDir"
proc AddDummy {name {link ""}} {
set t [clock seconds]
if {[string length $link] != 0} {
ioVirtual AddDir 0 $t $t "User" "Group" 0777 $name $link
} else {
ioVirtual AddDir 0 $t $t "User" "Group" 0777 $name {}
}
}
proc MirrorDir {vPath oPath} {
foreach vEntry [resolve list $vPath] {
# putlog "entry: $vEntry"
lassign $vEntry name type uid user gid group size mode attributes \
winLastTime unixLastTime winAltTime unixAltTime subDirCount \
pathList chattrList uptime
# it's important the the mode passed to ioVirtual only contain the 0777
# bits set else it complains and rejects it.
set mode [expr {$mode & 0777}]
if {$type == "d"} {
if {$name == "." || $name == ".."} continue
ioVirtual AddDir $size $unixLastTime $unixAltTime $user $group $mode $name "[file join $vPath $name]"
#ioVirtual AddLink [file join $vPath $name] $name
} elseif {$type == "f"} {
ioVirtual AddFile $size $unixLastTime $unixAltTime $user $group $mode $name ":[file join $vPath $name]"
} elseif {$type == "l"} {
# putlog "type $type - [lindex $chattrList 1] -- $mode"
ioVirtual AddDir $size $unixLastTime $unixAltTime $user $group $mode $name [lindex $chattrList 1]
} else {
return -code error "unknown <type>: $type"
}
}
return 1
}
proc ProcessArgs {} {
global ioArgs mDir vDir
putlog "mirror: $ioArgs"
# need to strip off quotes from arguments
set fileName [string range [lindex $ioArgs 0] 1 end-1]
set globPattern [string range [lindex $ioArgs 1] 1 end-1]
set oldPattern [string range [lindex $ioArgs 2] 1 end-1]
set exists [lindex $ioArgs 3]
set cmd [lindex $ioArgs 4]
if {$globPattern != ""} {
# this can either be a real glob like *.txt, or it can be
# the name of a file
}
set pathList [file split $fileName]
if {![string equal -nocase [lindex $pathList 1] $vDir]} {
putlog "Not in virtual dir!"
return 0
}
set target [file join / $mDir {*}[lrange $pathList 2 end]]
set real [resolve PWD $target]
putlog "$target = $real"
if {$real == ""} {
putlog "failed to resolve"
return 0D
}
if {[file isdirectory $real]} {
return [MirrorDir $target $fileName]
}
if {[file isfile $real]} {
putlog "resolved: $target -> $real"
AddDummy "||RESOLVED||" $target
return 1
}
if {$exists != "" && $exists} {
# doesn't exist... just ignore
return 0
}
putlog "non-exist resolved: $target -> $real"
AddDummy "||RESOLVED||" $target
return 1
}
return [ProcessArgs]