#!/usr/bin/wish namespace eval mount { # Default images for various device types. # First image in list - for mounted device, second - for empty set stdImages(floppy) [list [image create photo -data { R0lGODlhEAAQAMIAAAAAgAAAAP//AODg4P///8DAwP///////yH+Dk1hZGUgd2l0aCBHSU1Q ACH5BAEKAAcALAAAAAAQABAAAAM7CBDcHgoCQasVUY3N+8gAIY4kAXooWK4n2qkrCSp0XUtK oe/FXfcAno8GFNJwwdxumFPqbjje8vioPhIAOw== }] [image create photo -data { R0lGODlhEAAQAOMAAAAAgAAAAP//AODg4P///4CAgMDAwP8AAP////////////////////// /////////yH+Dk1hZGUgd2l0aCBHSU1QACH5BAEKAAgALAAAAAAQABAAAARLEIBAqw0SA8G7 F5k0jGQ5hAChriyBFnAsx1hh3Hh+F0HR/gRYT6c7GIQ2nCyHPAorMecQx2LyZliaRmLg4iQo rvcGnmyJXfBlvY4AADs= }]] set stdImages(cdrom) [list [image create photo -data { R0lGODlhEAAQAMIAAICAgP//AMDAwAAAAAD//wD/AP///////yH+Dk1hZGUgd2l0aCBHSU1Q ACH5BAEKAAcALAAAAAAQABAAAANReKrQvZCBEIQdIx5AaLUXBBRE91mGkDEFSYGpylhth4Iy AJLAoOOZHy0zwOVwhh4HuIGhCgECaKWL0aLS1cZ6xWqbuBblK9kVMJpFA0NOuxUJADs= }] [image create photo -data { R0lGODlhEAAQAMIAAICAgP//AMDAwAAAAAD//wD/AP///////yH+Dk1hZGUgd2l0aCBHSU1Q ACH5BAEKAAcALAAAAAAQABAAAANKeKrQvZCBEIQdIx5AaLUXBBRE91mGkElO624AKM/AABh4 ruONPdOCXgzUkgmDPYytgfSBdMaaa+pYbWaFAsW6YFqyGE23FhabNQkAOw== }]] set stdImages(zip) [list [image create photo -data { R0lGODlhEAAQAMIAAAAAAAAAgMDAwJYNH////+Dg4P//AP///yH+Dk1hZGUgd2l0aCBHSU1Q ACH5BAEKAAcALAAAAAAQABAAAANJCLrcGkHIOWF4kVJ7od4W4H0SJ3IoeqbsyqrQIA9EbRPQ WexD0e+7HKRGs81wnYCP1/sNhIEikVB8JmdNn6wANXgN2C/U0YAkAAA7 }] [image create photo -data { R0lGODlhEAAQAMIAAOgNDYCAgMDAwAAAAP////8AAP///////yH+Dk1hZGUgd2l0aCBHSU1Q ACH5BAEKAAcALAAAAAAQABAAAAM9eLrc/g1IoChc9uKaJ8tHV43fFlZBqq6qEghwLMPBEBB4 ruOpPc8FQe8VW8mGwt5gqUr6YrpjjUVVDTSPBAA7 }]] set stdImages(memoryCard) [list [image create photo -data { R0lGODdhEAAQAMIAAAAAAPhAQIgAAOD8+Pj8+ODg4OD88Pj8ACwAAAAAEAAQAAADSAi63Bow SvmmjeDqrC3vVCQI0DiGAZmuXjm8hEnMECcUxVDcOF6XhIEgFoT9ArubMIcbHAezGRQafL50 WIPueOh6v4ejowFJAAA7 }] [image create photo -data { R0lGODdhEAAQAMIAAOiouPj8+ICAgMDAwAAAAPgAAAAAAAAAACwAAAAAEAAQAAADMwi63P4w ykkrCMFiJrr/niIMZGmSAiFgbMt26nkWAzyWn2nXMOF7vFippUuBjh6Ca7lMAAA7 }]] proc listDevices {} { variable mountedDevices variable ejectableDevices variable deviceWidgets variable deviceImage variable stdImages frame .mount set index 1 set f [open /etc/fstab] foreach m [split [read $f] "\n"] { if {![string length $m]||[regexp "^\[ \t\]*#" $m]} continue set opts [split [lindex $m 3] ","] set device [lindex $m 0] if {[lsearch -exact $opts user]==-1||[regexp ":" $device]} continue set mpoint [lindex $m 1] # Guessing switch -glob $device { /dev/fd* { #floppy set deviceImage($mpoint) $stdImages(floppy) } /dev/[sh]d[a-z][0-9] { #partitioned drive regexp {/dev/.d[a-z]} $device ejpath if {[regexp zip $mpoint]} { # assume it is Zip set ejectableDevices($mpoint) $ejpath set deviceImage($mpoint) $stdImages(zip) } else { # USB flashcard or something if {[regexp ejectable $m]} { set ejectableDevices($mpoint) $ejpath } set deviceImage($mpoint) $stdImages(memoryCard) } } default { # anything else should be CD-rom set ejectableDevices($mpoint) $device set deviceImage($mpoint) $stdImages(cdrom) } } set deviceWidgets($mpoint) .mount.d$index incr index label $deviceWidgets($mpoint) bind $deviceWidgets($mpoint) <1> [list ::mount::changeDeviceStatus $mpoint] pack $deviceWidgets($mpoint) -side left } close $f scanMtab pack .mount -side right } proc scanMtab {args} { variable deviceWidgets variable deviceImage set f [open /etc/mtab] foreach m [split [read $f] "\n"] { if {![llength $m]} continue set mpoint [lindex $m 1] if [info exists deviceWidgets([lindex $m 1])] { set mounted($mpoint) 1 } } close $f foreach {mpoint widget} [array get deviceWidgets] { if [info exists mounted($mpoint)] { $widget configure -image [lindex $deviceImage($mpoint) 0] balloonhelp $widget "$mpoint (mounted)" } else { $widget configure -image [lindex $deviceImage($mpoint) 1] balloonhelp $widget "$mpoint" } } } proc changeDeviceStatus {mpoint} { variable deviceWidgets variable deviceImage if {[$deviceWidgets($mpoint) cget -image]=="[lindex $deviceImage($mpoint)\ 1]"} { mount $mpoint } else { unmount $mpoint } scanMtab } proc mount {mpoint} { global errorCode if [catch {exec mount $mpoint} msg] { # mount returns non-zero if {$errorCode!="NONE"} { tk_messageBox -title "Mount failed" -message $msg -icon error\ -type ok return } else { # No error, but there is warning. Mounted read only if [string length $msg] { tk_messageBox -title "Warning" -message $msg -icon warning \ -type ok } } } } proc unmount {mpoint} { global eject ejectableDevices if [catch {exec umount $mpoint} msg] { tk_messageBox -title "Umount failed" -message $msg -icon error\ -type ok return } if {[info exists ejectableDevices($mpoint)]} { if [catch {exec eject $ejectableDevices($mpoint) 2>/dev/null} msg] { tk_messageBox -title "Eject failed" -message "Device is unmounted\ but cannot be ejected:\n$msg" -icon error\ -type ok } } } listDevices } notifier ::mount::scanMtab