proc DumpObject_html {db obj} {
# Show type and open bracket
append ret [dbobj $obj type] " " [dbobj $obj fsid] "/" [dbobj $obj subobjid] " {\n"
# Show the construction status
if { [dbobj $obj construction] } {
append ret " UNDER CONSTRUCTION\n"
}
# dump the body of the object
foreach attr [dbobj $obj attrs] {
if { [string match "0x*" $attr] } {
append ret " (attribute $attr not in schema)\n"
continue
}
append ret [format { %-14s =} $attr]
set val [dbobj $obj get $attr]
if { [dbobj $obj attrtype $attr] == "object" } {
foreach subObj [dbobj $obj gettarget $attr] {
append ret " " [html_link "/object/$subObj" $subObj]
}
} elseif { [dbobj $obj attrtype $attr] == "file" && [catch {mfs streamsize $val}] } {
append ret " " [html_link "/object/$val" $val]
} else {
append ret " " [dbobj $obj get $attr]
}
append ret "\n"
}
# close bracket
append ret "}"
}
proc do_dir {chan path} {
global tzoffset
puts $chan [html_start "Directory listing of $path"]
puts $chan [html_table_start "" "Directory listing of $path" "colspan=5"]
puts $chan [tr "ALIGN=LEFT" [th "Name"] [th "Type"] [th "Id"] [th "Date Time"] [th "Size"]]
ForeachMfsFile fsid name type $path "" {
RetryTransaction {
if {[catch {set size [FileSize $type $fsid]}] != 0} {
set size "N/A"
}
if {[catch {set seconds [expr [mfs moddate $fsid] + $tzoffset]
set date [clock format $seconds -format "%D %R"]}] != 0} {
set date "N/A"
}
}
if {[string range $path end end] != "/"} {
append path "/"
}
puts -nonewline $chan "
"
if { $path == "/Resource/Image/" } {
puts -nonewline $chan [html_link "/img/$name.png" $name]
} else {
regsub -all {\.} $name {\\.} tname
puts -nonewline $chan [html_link "/mfs$path[httpMapReply $tname]" $name]
}
puts -nonewline $chan " | $type | "
if { $type == "tyDb" || $type == "tyFile" } {
puts -nonewline $chan [html_link "/object/$fsid" $fsid]
} else {
puts -nonewline $chan $fsid
}
puts $chan " | $date | $size |
"
}
puts -nonewline $chan [html_table_end]
puts $chan [html_end]
}
proc do_object {chan path objectid} {
global db
puts $chan [html_start $path]
puts $chan ""
RetryTransaction {
if { [regexp {([0-9]*)/(.*)} $objectid junk fsid subobjid] } {
set obj [db $db openidconstruction $fsid $subobjid]
} else {
set obj [db $db openid $objectid]
}
puts $chan [DumpObject_html $db $obj]
}
puts $chan " |
"
puts $chan [html_end]
}
proc do_file {chan objectid} {
RetryTransaction {
set size [mfs size $objectid]
set chunksize 4096
fconfigure $chan -translation binary
for {set i 0} {$i < $size} {incr i $chunksize} {
set s [min $chunksize [expr $size - $i]]
set chunk [mfs getpart $objectid $i $s]
puts -nonewline $chan $chunk
}
}
}
proc action_object {chan objectid env} {
global db
if {[string index $objectid 0] == "/"} {
set objectid [string range $objectid 1 end]
}
regsub {/.*} $objectid {} fsid
RetryTransaction {
set object [db $db canopenidconstruction $fsid]
}
if {$object} {
do_object $chan "" $objectid
} elseif {[catch {mfs streamsize $val}]} {
do_file $chan $objectid
}
}
proc action_mfs {chan path env} {
if {$path == "" } {
set path "/"
}
if {[catch {RetryTransaction {mfs find "$path"}} l] != 0} {
puts $chan [html_start ""]
puts $chan "PATH: $path
"
puts $chan $l
puts $chan [html_end]
} else {
set type [lindex $l 1]
if {$type == "tyDir"} {
do_dir $chan $path
} elseif {$type == "tyDb"} {
do_object $chan $path [lindex $l 0]
} elseif {$type == "tyFile"} {
do_file $chan [lindex $l 0]
}
}
}
register_module "mfs" "MFS" "Browse through the MFS FileSystem"