home *** CD-ROM | disk | FTP | other *** search
/ PCNET 2006 September - Disc 1 / PCNET_CD_2006_09.iso / linux / puppy-barebones-2.01r2.iso / pup_201.sfs / usr / lib / mut / mut.tcl < prev   
Encoding:
Tcl/Tk script  |  2006-06-17  |  44.1 KB  |  1,459 lines

  1. #!/usr/bin/wish
  2. #
  3. # MUT written by Jesse Liley for Puppy Linux 2005
  4. # bugs, fixes, suggestions, email: Jesse.Liley@gmail.com
  5. #
  6. # Free software, use at own risk! LGPL, please keep comments.
  7. #
  8. # Images used taken from Mandrake Linux download 10.0 /usr/share/icons
  9. # So I hope they are free to distribute :-)
  10. #
  11.  
  12. package require Tcl 8.5
  13.  
  14. #Here you can set mount points that MUT will not allow to be unmounted.
  15. lappend NoUnmounts "/"  ; # This one is a generic for any Linux, its actually quite bad to unmount this one.
  16. if {![file exists /etc/multisessionmediatype]} {
  17.     # this file /etc/multisessionmediatype indicates that 
  18.     lappend NoUnmounts "/mnt/home"  ; # This one is a Puppy Linux specific one, it is the container fs for pup001 file
  19. }
  20. #lappend NoUnmounts "/mnt/home" ; #add any more here, as many as you like, don't forget to uncomment.
  21.  
  22. #Puppy2 very specific: never unmount anything under /initrd/
  23. lappend PuppyNoUnmount "/initrd/"
  24.  
  25. #Here you can set devices that start out not being scanned, e.g. for if the scan time takes a while and you don't really want to wait every refresh.
  26. array unset NoScanMedia   ;# this line defines the array.
  27. set NoScanMedia(fd0) "noscan"  ;# floppy disk is fd0
  28. set NoScanMedia(fd1) "noscan"  ;# second floppy disk is fd1, this is ok if one or none floppy drives in system.
  29. #set NoScanMedia(fd0) "noscan" ;# add others, replace fd0 with device name
  30.  
  31.  
  32.  
  33. # Here in this function you can change the scripted events attached to MUT click actions (mounting etc...)
  34.  
  35. proc trigger_external_event {event device} {
  36.     set mounted 0
  37.     set dev $device
  38.     if {[info exists ::etc_fstab($dev)]} {
  39.         set mntloc "$::etc_fstab($dev)"
  40.     } else {
  41.         set mntloc "/mnt/$dev"
  42.     }
  43.     # if we chose bad, allow fallback to some other location.
  44.     foreach devpath [array names ::mounteds] {
  45.         set d [lindex [split $devpath / ] end]
  46.         set mp [lindex [split $::mounteds($devpath) | ] 0 ]
  47.         if {$mp == $mntloc && $dev != $d} {
  48.             set mntloc "/mnt/$dev"
  49.         }
  50.     }
  51.  
  52.     set rescan_delay 2000
  53.     catch {
  54.         set mntloc [lindex [split $::mounteds(/dev/$dev) |] 0]
  55.         set mounted 1
  56.     }
  57.     if {$::debug} { puts "User clicked on action with device $event /dev/$dev $mntloc $mounted" }
  58.     switch $event {
  59.         "cdplay" {   ;# Commands to open application to play audio CD
  60.                 set cdinfo ""
  61.                 catch "exec $::mut/bin/cdrominfo /dev/$dev -p" cdinfo
  62.                 if {$::debug} {puts "got cdinfo for /dev/$dev, which is  $cdinfo"}
  63.                 if { [lindex [split $cdinfo '|'] 7] == "Audio" || [lindex [split $cdinfo '|'] 7] == "Mixed"} {
  64.                     catch "exec /usr/local/bin/gplaycd -c /dev/$dev &"
  65.                 }
  66.                 set rescan_delay 200
  67.             }
  68.         "cdmount" {  ;# Commands to open application to show data files on CD
  69.                 catch "exec mkdir $mntloc"
  70.                 set fs "iso9660"
  71.                 catch "exec mount /dev/$dev $mntloc -t iso9660"
  72.                 catch "exec rox -d $mntloc"
  73.                 catch {exec "mount > /etc/mtab"}
  74.                 set rescan_delay 500
  75.             }
  76.         "cdunmount" {;# Commands to close application to show data files on CD
  77.                 catch "exec rox -D $mntloc"
  78.                 catch "exec fuser -k -m $mntloc"
  79.                 catch "exec umount $mntloc"
  80.                 catch {exec "mount > /etc/mtab"}
  81.                 set rescan_delay 500
  82.             }
  83.         "mount" {   ;# Commands to open application to show data files on disk
  84.                 catch "exec mkdir $mntloc"
  85.                 set fs ""
  86.                 catch "exec $::mut/bin/guess_fstype /dev/$dev" fs
  87.                 if {$::debug} {puts "got fs for /dev/$dev, which is $fs"}
  88.                 catch "exec mount /dev/$dev $mntloc -t $fs"
  89.                 catch "exec rox -d $mntloc"
  90.                 catch {exec "mount > /etc/mtab"}
  91.                 set rescan_delay 500
  92.             }
  93.         "unmount" { ;# Commands to close application to show data files on disk
  94.                 if {$mounted} {
  95.                     catch "exec rox -D $mntloc"
  96.                     catch "exec fuser -k -m $mntloc"
  97.                 }
  98.                 catch "exec umount $mntloc"
  99.                 catch {exec "mount > /etc/mtab"}
  100.                 set rescan_delay 400
  101.             }
  102.         "gxinedvd" { ;# Launch a dvd player
  103.                 catch "exec gxine dvd:/"
  104.                 set rescan_delay 2000
  105.             }
  106.         "rox"    {   ;# Launch file browser on already mounted partition/disk/cd
  107.                 catch "exec rox -d $mntloc"
  108.                 set rescan_delay 200
  109.             }
  110.         "eject" {   ;# Eject disc media Cdrom DVD etc..
  111.                 if {$mounted} {
  112.                     catch "exec rox -D $mntloc"
  113.                     catch "exec fuser -k -m $mntloc"
  114.                     catch "exec umount $mntloc"
  115.                     catch {exec "mount > /etc/mtab"}
  116.                 }
  117.                 catch "exec $::mut/bin/cdrominfo /dev/$dev -e"
  118.                 # This application locks up during the trayclose event, so rescan shortlyafter
  119.                 set rescan_delay 200
  120.             }
  121.         "trayclose" {;# Close tray holder mechanism on disc media Cdrom DVD etc..
  122.                 catch "exec $::mut/bin/cdrominfo /dev/$dev -c"
  123.                 # This application locks up during the trayclose event, so rescan shortlyafter
  124.                 set rescan_delay 200
  125.             }
  126.         "initrdswapoff" {;# unmount initrd swap filesystem
  127.                 catch "exec swapoff /initrd/dev/$dev"
  128.                 set rescan_delay 1000
  129.             }
  130.         "swapoff" {;# unmount swap filesystem
  131.                 catch "exec swapoff /dev/$dev"
  132.                 set rescan_delay 1000
  133.             }
  134.         "swapon" { ;# mount swap filesystem
  135.                 catch "exec swapon /dev/$dev"
  136.                 set rescan_delay 1000
  137.             }
  138.  
  139.  
  140.         "scan" {  ;# Activate Mut scanning this device (it may be slow to respond)
  141.                 array unset ::NoScanMedia $dev
  142.                 if {$::debug} {puts "names NoScan [array names ::NoScanMedia]"}
  143.                 set rescan_delay 100
  144.             }
  145.         "noscan" { ;# Deactivate Mut scanning this device (it may be slow to respond)
  146.                 set ::NoScanMedia($dev) "noscan"
  147.                 if {$::debug} {puts "names NoScan [array names ::NoScanMedia]"}
  148.                 set rescan_delay 100
  149.             }
  150.         default { msg "no code to run for event \"$event\"" }
  151.     }
  152.     return $rescan_delay
  153. }
  154.  
  155. # This function calculates home path of application, yay, no need to configure it :-) even if symlinked to it.
  156. # this is generic, it could apply to any tcl app that has an application directory structure.
  157. proc homepath { } {
  158.     set cmd "pwd"
  159.     catch $cmd this_pwd
  160.     if {[string index $::argv0 0] == "/"} {
  161.         set path "$::argv0"
  162.     } else {
  163.         set path "$this_pwd/$::argv0"
  164.     }
  165.     # if it is a symlink from say /usr/local/bin/mut, follow the link.
  166.     if { [file type $path] == "link" } {
  167.         set path "$this_pwd/[file readlink $path]"
  168.     }
  169.     set path "$path/.."
  170.     set plist [split $path "/"]
  171.     set n [llength $plist]
  172.     for {set i 0} {$i < $n} {incr i} {
  173.         if {[lindex $plist $i] == "."} { 
  174.             set a [expr "$i - 1" ]
  175.             set b [expr "$i + 1" ]
  176.             set plist [concat [lrange $plist 0 $a] [lrange $plist $b end ] ]
  177.             incr n -1
  178.         }
  179.     }
  180.     set n [llength $plist]
  181.     set olist ""
  182.     for {set i 0} {$i < $n} {incr i} {
  183.         if {[lindex $plist $i] == ".."} {
  184.             set olist [lrange $olist 0 [expr "[llength $olist]-2"]]
  185.         } else {
  186.             lappend olist [lindex $plist $i]
  187.         }
  188.     }
  189.     set path "[join $olist "/"]/"
  190.     return $path
  191. }
  192.  
  193. proc in_rect {x y x1 y1 x2 y2} {
  194.     if {$x >= $x1 && $x <= $x2 && $y >= $y1 && $y <= $y2} {return 1}
  195.     return 0
  196. }
  197.  
  198. proc show_icons {} {
  199.     set wx [lindex [split [wm geometry .] "+x"] 0]
  200.     set wy [lindex [split [wm geometry .] "+x"] 1]
  201.     set xpos [expr "$wx - 0.5 * [image width ::img::img(tux)] -4"]
  202.     set ypos [expr "$wy - 20"]
  203.     .boxc create image $wx $ypos -image ::img::img(tux) -anchor se
  204.  
  205.     set ypos [expr "$wy - 20"]
  206.  
  207.  
  208.     set xpos [expr "$wx - 0.5 * [image width ::img::img(refresh)] -4"]
  209.     .boxc create image $xpos 16 -image ::img::img(refresh) 
  210. }
  211.  
  212. proc full_refresh_display {} {
  213.     .boxc delete all
  214.     array unset ::actions
  215.     set ::infolist {}
  216.     run_full_scan
  217.     Show_Devices
  218.     show_icons
  219.     if {[file exists /proc/bus/usb/devices]} {
  220.         set ::last_hotplug [file mtime /proc/bus/usb/devices]
  221.     }
  222. }
  223.  
  224. proc quick_update_display {} {
  225.     .boxc delete all
  226.     array unset ::actions
  227.     set ::infolist {}
  228.     run_quick_update
  229.     Show_Devices
  230.     show_icons
  231. }
  232.  
  233. proc check_click_action {x y} {
  234.     set done false
  235.     set rescan_delay 2000
  236.     foreach id [array names ::actions *] {
  237.         set action $::actions($id)
  238.         foreach {x1 y1 x2 y2} [lrange $action 1 4] {
  239.             if {[in_rect $x $y $x1 $y1 $x2 $y2]} {
  240.                 #puts "event trigger [lindex $action 0] for [lindex $action 5]"
  241.                 set done true
  242.                 set rescan_delay [trigger_external_event [lindex $action 0] [lindex $action 5]]
  243.             }
  244.         }
  245.     }
  246.     if {$done == false } { after 100 full_refresh_display } else { after $rescan_delay full_refresh_display }
  247.  
  248. proc msg { msg } {
  249.     tk_dialog .msg "Message Window" $msg info 0 OK
  250. }
  251.  
  252. proc remove_empties str {
  253.     set i 0
  254.     set i [lsearch $str {}]
  255.     while {$i >= 0} {
  256.         set str [lreplace $str $i $i]
  257.         set i [lsearch $str {}]
  258.     }
  259.     return $str
  260. }
  261.  
  262. proc grab_fs_vol {fs dev} {
  263.     set results ""
  264.     if {[lsearch [list "iso9660" "vfat" "ext2"] $fs]=={}} {
  265.         if {$::debug} {puts "Unknown fs $fs for grab_fs_vol"}
  266.         return ""
  267.     }
  268.     catch "exec $::mut/bin/label_$fs /dev/$dev" results
  269.     set results [lindex [split $results "\n"] 0]
  270.     set results [string trimleft [string trimright $results]]
  271.     return $results
  272. }
  273.  
  274. proc majorBus__get_list {} {
  275.     set rec false
  276.     array unset ::majorBus
  277.     array unset ::majorBusRev
  278.     catch {
  279.         set fid [open "/proc/devices" r]
  280.         if {$::debug} {puts "in majorBus__get_list"}
  281.         while {![eof $fid]} {
  282.             gets $fid str
  283.             set line [remove_empties [split $str " "]]
  284.             if {$rec == true && [lindex $line 1] > 1} {
  285.                 set ::majorBus([lindex $line 0]) [lindex $line 1]
  286.                 set ::majorBusRev([lindex $line 1]) [lindex $line 0]
  287.     if {$::debug} {puts " ::majorBus([lindex $line 0]) $::majorBus([lindex $line 0]) "}
  288.             }
  289.             if {[lindex $line 0 ] == "Block"} {set rec true}
  290.         }
  291.         close $fid
  292.     }
  293. }
  294.  
  295. # scan media or model file.
  296. proc scan_ide_medium {bus lun scan_me} {
  297.     if {$bus=="" || $lun=="" || $scan_me==""} {return ""}
  298.     set medium ""
  299.     catch {
  300.         set bd_fd [open "/proc/ide/$bus/$lun/$scan_me" r]
  301.         gets $bd_fd medium
  302.         close $bd_fd
  303.     }
  304.     return $medium
  305. }
  306.  
  307. proc main_or_part {str} {
  308.     for {set i 0} {$i < [string length $str] } {incr i} {
  309.         if {[string index $str $i] >= "0" && [string index $str $i] <= "9"} {
  310.             if {[string range $str $i end] >= 1 && [string range $str $i end] <= 16} {
  311.                 return part
  312.             }
  313.         }
  314.     }
  315.     return main
  316. }
  317.  
  318. proc diskStats26__get_list {quick} {
  319.     set rec false
  320.     array unset ::diskStats
  321.     catch {
  322.         set fid [open "/proc/diskstats" r]
  323.         if {$::debug} {puts "in diskStats26__get_list"}
  324.         while {![eof $fid]} {
  325.             gets $fid str
  326.             set line [remove_empties [split $str " "]]
  327.             foreach did $::grabdevs {
  328.                 if {[string range [lindex $line 2] 0 1] == $did} {
  329.                     set media ""
  330.                     if {$did == "fd"} {
  331.                         set media floppy
  332.                     }
  333.                     if {$did == "hd"} {
  334.                         if {[main_or_part [lindex $line 2]] == "main"} {
  335.                             set media [scan_ide_medium $::majorBus([lindex $line 0]) [lindex $line 2] "media"]
  336.                         } else {
  337.                             set media part
  338.                         }
  339.                     }
  340.                     if {$did == "sd"} {
  341.                         if {[main_or_part [lindex $line 2]] == "main"} {
  342.                             set media disk
  343.                         } else {
  344.                             set media part
  345.                         }
  346.                     }
  347.                     if {$did == "scd" || $did=="sr"} {
  348.                         if {[main_or_part [lindex $line 2]] == "main"} {
  349.                             set media cdrom
  350.                         } else {
  351.                             set media part
  352.                         }
  353.                     }
  354.                     set ::diskStats([lindex $line 2]) "[lindex $line 0].[lindex $line 1].$::majorBus([lindex $line 0]).$media"
  355.                     if {$::debug} {puts "set ::diskStats([lindex $line 2]) $::diskStats([lindex $line 2])"}
  356.                 }
  357.             }
  358.             if {[lindex $line 0 ] == "Block"} {set rec true}
  359.         }
  360.         close $fid
  361.     }
  362. }
  363.  
  364. proc diskStats24__get_list {quick} {
  365.     set rec false
  366.     array unset ::diskStats
  367.     if {$::debug} {puts "in diskStats24__get_list"}
  368.     set addfd false
  369.     catch {
  370.         if {$::majorBusRev(fd)  >= 0} {
  371.             set ::diskStats(fd0) "$::majorBusRev(fd).0.fd.floppy"
  372.             if {$::debug} {puts "set ::diskStats(fd0) $::diskStats(fd0)"}
  373.             #second floppy disk here:
  374.             #set ::diskStats(fd1) "$::majorBusRev(fd).1.fd.floppy"
  375.             #if {$::debug} {puts "set ::diskStats(fd1) $::diskStats(fd1)"}
  376.         }
  377.     }
  378.     foreach dev [lsort [array names ::partitions]] {
  379.         set str $::partitions($dev)
  380.         set line [remove_empties [list [lindex $str 1] [lindex $str 2] $dev ]]
  381.         if {[llength $line] < 3 } {continue}
  382.         foreach did $::grabdevs {
  383.             if {[string range [lindex $line 2] 0 1] == $did} {
  384.                 set media ""
  385.                 if {$did == "fd"} {
  386.                     set media floppy
  387.                 }
  388.                 if {$did == "hd"} {
  389.                     if {[main_or_part [lindex $line 2]] == "main"} {
  390.                         set media [scan_ide_medium $::majorBus([lindex $line 0]) [lindex $line 2] "media"]
  391.                     } else {
  392.                         set media part
  393.                     }
  394.                 }
  395.                 if {$did == "sd"} {
  396.                     if {[main_or_part [lindex $line 2]] == "main"} {
  397.                         set media disk
  398.                     } else {
  399.                         set media part
  400.                     }
  401.                 }
  402.                 if {$did == "scd" || $did=="sr"} {
  403.                     if {[main_or_part [lindex $line 2]] == "main"} {
  404.                         set media cdrom
  405.                     } else {
  406.                         set media part
  407.                     }
  408.                 }
  409.                 set ::diskStats([lindex $line 2]) "[lindex $line 0].[lindex $line 1].$::majorBus([lindex $line 0]).$media"
  410.                 if {$::debug} {puts "set ::diskStats([lindex $line 2]) $::diskStats([lindex $line 2])"}
  411.             }
  412.         }
  413.         if {[lindex $line 0 ] == "Block"} {set rec true}
  414.     }
  415. }
  416.  
  417. proc diskStats__get_list {quick} {
  418.     if {$::Kernel_Version=="2.4"} {diskStats24__get_list $quick}
  419.     if {$::Kernel_Version=="2.6"} {diskStats26__get_list $quick}
  420. }
  421.  
  422. proc partitions__get_list {} {
  423.     array unset ::partitions
  424.     catch {
  425.         set fid [open "/proc/partitions" r]
  426.         while {![eof $fid]} {
  427.             gets $fid str
  428.             set shortlist [remove_empties [split $str]]
  429.             set dev [lindex $shortlist 3]
  430.             if {[llength $str] == 4 && [lindex $str 0] > 0 && [lindex $shortlist 2] > 1 } {
  431.                 set mytimer [clock clicks -milliseconds]
  432.                 set openok true
  433.                 set catchinfo ""
  434.                 if {$::Kernel_Version=="2.4" && [string range $dev 0 1] == "sd"} {
  435.                     # Sigh, we have to force the kernel to look at the hardware:
  436.                     if {[info exists ::NoScanMedia($dev)]} {
  437.                         if {$::debug} { puts "not scan $dev"}
  438.                     } else {
  439.                         set openok false
  440.                         catch {
  441.                             if {$::debug} { puts "about to scan $dev"}
  442.                             set bd_fd [open "/dev/$dev" r]
  443.                             close $bd_fd
  444.                             set openok true
  445.                         } catchinfo
  446.                     }
  447.                 }
  448.                 if {$openok == false} {
  449.                     if {$::debug} { puts "device not working? /dev/$dev  $catchinfo" }
  450.                     if {[info exists ::NoScanMedia($dev)]} {
  451.                         if {$::debug} {puts "already in NoScanMedia $::NoScanMedia($dev)"}
  452.                     } else {
  453.                         #if it exists but cannot be opened, make it a noscan object
  454.                         if {[file exists /dev/[lindex $shortlist 3] ] == 1} {
  455.                             set ::NoScanMedia([lindex $shortlist 3]) "noscan"
  456.                         }
  457.                     }
  458.                 }
  459.                 set time_length [expr "[clock clicks  -milliseconds] - $mytimer"]
  460.                 if {$::debug} { puts "open scan time is $time_length 1000ths of a second, $shortlist"}
  461.                 set ::partitions([lindex $shortlist 3]) \
  462.                     [list [format "%1.1f Mb" [expr "[lindex $shortlist 2]/1000.0"]] [lindex $shortlist 0] [lindex $shortlist 1]]
  463.                 if {$::debug} {puts "set  ::partitions($dev) = $::partitions($dev)"}
  464.             }
  465.             if {[llength $str] == 4 && [lindex $str 0] > 0 && [lindex $shortlist 2] == 1 } {
  466.                 set ::partitions($dev) "extended"
  467.             }
  468.         }
  469.         close $fid
  470.     }
  471.     
  472.     # we have to scan for extra devices here in kernel 2.4
  473.     # Scan for IDE removable disc drives (cdroms)
  474.     if {$::Kernel_Version=="2.4"} {
  475.         set ide_devs [glob /dev/hd*]
  476.         set ide_scan {}
  477.         set devlist [array names ::partitions]
  478.         foreach device $ide_devs {
  479.             set dev [lindex [split $device / ] 2]
  480.             set atpos [lsearch -exact $devlist $dev]
  481.             if {$atpos < 0 && [string length $dev] == 3} {
  482.                 set found false
  483.                 set gl ""
  484.                 catch {
  485.                     set  gl [split [glob "/proc/ide/ide*/$dev"] /]
  486.                 }
  487.                 array unset ::cdromMedium $dev
  488.                 if {$gl == ""} {continue}
  489.                 set info ""
  490.                 lappend ide_scan $dev
  491.                 catch { exec $::mut/bin/stat_dev /dev/$dev } info
  492.                 if {$info ==""} {continue}
  493.                 set ::partitions($dev) [concat "device" [split $info |]]
  494.         if {$::debug} { puts "set  ::partitions($dev) = $::partitions($dev)" }
  495.                 #set ::diskStats($dev) "[lindex $info 0].[lindex $info 1].sr.cdrom"
  496.         #if {$::debug} { puts "set  ::diskStats($dev) = $::diskStats($dev)" }
  497.             }
  498.         }
  499.         if {$::debug} { puts "scan these devices... [lsort $ide_scan]" }
  500.     }
  501.     # Scan for SCSI/USB removable disc drives (cdroms)
  502.     if {$::Kernel_Version=="2.4" || $::Kernel_Version=="2.6"} {
  503.         set sr_devs [glob /dev/sr*]
  504.         set sr_scan {}
  505.         set devlist [array names ::partitions]
  506.         foreach device $sr_devs {
  507.             set dev [lindex [split $device / ] 2]
  508.             set atpos [lsearch -exact $devlist $dev]
  509.             if {$atpos < 0 && [string length $dev] == 3} {
  510.                 set found false
  511.                 set gl ""
  512.                 set cdinfo ""
  513.                 catch { exec $::mut/bin/cdrominfo /dev/$dev -p } cdinfo
  514.                 if {$cdinfo == ""} {continue}
  515.                 set info [split $cdinfo |]
  516.                 if {[llength $info ] < 10} {continue}
  517.                 lappend sr_scan $dev
  518.                 catch { exec $::mut/bin/stat_dev /dev/$dev } info
  519.                 set ::partitions($dev) [concat "device" [split $info |]]
  520.         if {$::debug} { puts "set  ::partitions($dev) = $::partitions($dev)" }
  521.             }
  522.         }
  523.         if {$::debug} { puts "scan these devices... [lsort $sr_scan]" }
  524.     }
  525. }
  526.  
  527. proc device_nodes__scan_for_make_additional {} {
  528.     foreach name [lsort [array names ::partitions]] {
  529.         if {[lsearch -exact $::existing_nodes $name] >= 0} {continue}
  530.         set info ""
  531.         catch { exec $::mut/bin/stat_dev /dev/$name } info
  532.         set info [split $info |]
  533.         if {[lindex $info 0]>0 && [llength $info] ==2} {
  534.             lappend ::existing_nodes $name
  535.         } else {
  536.             if {$::debug} {puts "ADDME $name info $info"}
  537.             if {$::debug} {puts "makedevs /dev/$name b [lindex $::partitions($name) 1] [lindex $::partitions($name) 2] 0 16 s" }
  538.             catch "exec makedevs /dev/$name b [lindex $::partitions($name) 1] [lindex $::partitions($name) 2] 0 16 s " ex_info
  539.             if {$::debug} {puts "execute info $ex_info" }
  540.         }
  541.     }
  542.     if {$::debug} {puts "devnodes include $::existing_nodes"}
  543. }
  544.  
  545. proc cdromMedium_get_list {quick} {
  546.     if {$quick=="true"} {return}
  547.     array unset ::cdromMedium
  548.     foreach dev [array names ::diskStats] {
  549.         set ds [split $::diskStats($dev) '.']
  550.         if {[lindex $ds 3] =="cdrom"} {
  551.             catch "exec $::mut/bin/cdrominfo /dev/$dev -p" cdinfo
  552.             set ::cdromMedium($dev) $cdinfo
  553.             if {$::debug} {puts "set  ::cdromMedium($dev) which is $cdinfo"}
  554.         }
  555.     }
  556. }
  557.  
  558. proc additional_scan_for {mnt} {
  559.     catch { exec $::mut/bin/stat_dev /dev/$mnt } info
  560.     set m [lindex [split $info |] 0]
  561.     set s [lindex [split $info |] 1]
  562.     if {$m !="" && $s!= ""} {
  563.         foreach dev [array names ::diskStats] {
  564.             if {$m == [lindex [split $::diskStats($dev) .] 0] &&
  565.                 $s == [lindex [split $::diskStats($dev) .] 1]} {
  566.                 if {$dev !="" && $mnt !=""} {
  567.                     set ::etc_fstab($dev) "/mnt/$mnt"
  568.                     if {$::debug} {puts "set ::etc_fstab($dev) = $::etc_fstab($dev)"}
  569.                     return
  570.                 }
  571.             }
  572.         }
  573.     }
  574. }
  575.  
  576. proc etc_fstab__get_list {} {
  577.     if {$::debug} {puts "in etc_fstab__get_list"}
  578.     array unset ::etc_fstab 
  579.     catch {
  580.         set fid [open "/etc/fstab" r]
  581.         while {![eof $fid]} {
  582.             gets $fid str
  583.             set sl [remove_empties [split $str]]
  584.             set dev [lindex $sl 0]
  585.             set mnt [lindex $sl 1]
  586.             set dev [lindex [remove_empties [split $dev /]] end]
  587.             if { $dev != "" &&
  588.                 $dev != "none" && 
  589.                 $dev != "tmpfs" && 
  590.                 $dev != "rootfs" && 
  591.                 $dev != "loop"} {
  592.                 if {$dev !="" && $mnt !=""} {
  593.                     set ::etc_fstab($dev) "$mnt"
  594.                     if {$::debug} {puts "set ::etc_fstab($dev) = $::etc_fstab($dev)"}
  595.                 }
  596.             }
  597.         }
  598.     }
  599.     close $fid
  600.     additional_scan_for dvd
  601.     additional_scan_for cdrom
  602.  
  603.     # Multisession DVD/CD should get mounted at /mnt/home if possible
  604.     set myhome /mnt/myhome
  605.     if {[file exists /etc/multisessionmediatype]} {
  606.         set cdburnerdrive ""
  607.         if {[file exists /etc/cdburnerdrive ]} {
  608.             catch {
  609.                 set fid [open /etc/cdburnerdrive r]
  610.                 gets $fid cdburnerdrive
  611.                 close $fid
  612.             }
  613.         }
  614.         if {$cdburnerdrive != ""} {
  615.             set do_set true
  616.             catch {
  617.                 if {$::etc_fstab($cdburnerdrive) == $myhome } {
  618.                     set do_set false
  619.                 }
  620.             }
  621.             if {$do_set} {
  622.                 set ::etc_fstab($cdburnerdrive) $myhome
  623.                 if {$::debug} {puts "set ::etc_fstab($cdburnerdrive) = $::etc_fstab($cdburnerdrive)"}
  624.             }
  625.         }
  626.     }
  627. }
  628.  
  629. proc mounteds__get_list {} {
  630.     if {$::debug} {puts "in mounteds__get_list"}
  631.  
  632.     set fs_list ""
  633.     catch "exec mount" fs_list
  634.     foreach line [split $fs_list '\n'] {
  635.         set sl [remove_empties [split $line]]
  636.         set dev [lindex $sl 0]
  637.         set mnt [lindex $sl 2]
  638.         if { [string compare -length 4 $dev "/dev"] == 0} {
  639.             set ::mounteds($dev) "$mnt|[join [lrange $sl 4 end ] |]"
  640.             if {$::debug} { puts " ::mounteds($dev) = $::mounteds($dev)"}
  641.         }
  642.     }
  643.  
  644.     # Kernel 2.6 swaps:
  645.     # Filename                                Type            Size    Used    Priority
  646.     # /dev/hda8                               partition       682720  0       -1
  647.  
  648.  
  649.     catch {
  650.         set fid [open "/proc/swaps" r]
  651.         while {![eof $fid]} {
  652.             gets $fid str
  653.             set sl [remove_empties [split $str]]
  654.             set swap [lindex $sl 0]
  655.             if { [string compare -length 4 $swap "/dev"] == 0} {
  656.                 set ::mounteds($swap) "swap|swap|"
  657.                 if {$::debug} { puts " ::mounteds($swap) = $::mounteds($swap)"}
  658.             }
  659.             if { [string compare -length 11 $swap "/initrd/dev"] == 0} {
  660.                 set swap [string range $swap 7 end]
  661.                 set ::mounteds($swap) "initrdswap|initrdswap|"
  662.                 if {$::debug} { puts " ::mounteds($swap) = $::mounteds($swap)"}
  663.             }
  664.         }
  665.         close $fid
  666.     }
  667. }
  668.  
  669. proc real_permit_unmount {mnt} {
  670.     if {[llength [lsearch -inline -all -exact $::NoUnmounts $mnt]] > 0} { return false }
  671.     foreach m $::PuppyNoUnmount {
  672.         if {[string match "$m*" $mnt] == 1} { return false }
  673.     }
  674.     return true
  675. }
  676.  
  677. proc permit_unmount {mnt} {
  678.     set r [real_permit_unmount $mnt]
  679.     if {$::debug} { puts " unmountable $mnt   $r "}
  680.     return $r
  681. }
  682.  
  683.  
  684. # dmesg example:
  685. # sd 6:0:0:0: Attached scsi removable disk sdb
  686.  
  687.  
  688. proc scsi_host_to_sd_location {} {
  689.     array unset ::scsi_drvr
  690.     array unset ::scsi_node
  691.     set info ""
  692.     catch { exec dmesg -s 65535 } info  
  693.     #puts " dmesg length [llength $info] "
  694.     set lines [split $info \n]
  695.     foreach line $lines {
  696.         set sl [remove_empties [split $line]]
  697.         if {[string range [lindex $sl 0] 0 3] == "scsi"} {
  698.             set n [string range [lindex $sl 0] 4 end]
  699.             #puts "scsi$n has driver: [lrange $sl 2 end]"
  700.             if {[join [lrange $sl 2 end]] == "SCSI emulation for USB Mass Storage devices"} {
  701.                 set ::scsi_drvr($n) "usb_storage"
  702.             } else {
  703.                 set ::scsi_drvr($n) [lrange $sl 2 end]
  704.             }
  705.         }
  706.         if {[lindex $sl 0] == "sd"} {
  707.             if {[lindex $sl 2] == "Attached"} {
  708.                 if {[lindex $sl 3] == "scsi"} {
  709.                     if {[lindex $sl 4] == "removable"} {
  710.                         set n [lindex [split [lindex $sl 1] :] 0]
  711.                         #puts "scsi$n == [lindex $sl 6] "
  712.                         set ::scsi_node([lindex $sl 6]) $n
  713.                     }
  714.                     if {[lindex $sl 4] == "disk"} {
  715.                         set n [lindex [split [lindex $sl 1] :] 0]
  716.                         #puts "scsi$n == [lindex $sl 5] "
  717.                         set ::scsi_node([lindex $sl 5]) $n
  718.                     }
  719.                 }
  720.             }
  721.         }
  722.     }
  723.  
  724. #Jun 15 03:21:33 (none) user.info kernel: scsi2 : sata_nv
  725. #Jun 15 03:21:33 (none) user.info kernel: scsi3 : sata_nv
  726. #Jun 15 03:21:33 (none) user.notice kernel: sd 2:0:0:0: Attached scsi disk sda
  727. #Jun 14 19:22:26 (none) user.info kernel: scsi4 : SCSI emulation for USB Mass Storage devices
  728. #Jun 14 19:22:26 (none) user.info kernel: scsi5 : SCSI emulation for USB Mass Storage devices
  729. #Jun 14 19:22:31 (none) user.notice kernel: sd 4:0:0:0: Attached scsi removable disk sdb
  730. #Jun 14 19:22:31 (none) user.notice kernel: sd 4:0:0:1: Attached scsi removable disk sdc
  731. #Jun 14 19:22:31 (none) user.notice kernel: sd 4:0:0:2: Attached scsi removable disk sdd
  732. #Jun 14 19:22:31 (none) user.notice kernel: sd 4:0:0:3: Attached scsi removable disk sde
  733. #Jun 14 19:22:31 (none) user.notice kernel: sd 5:0:0:0: Attached scsi removable disk sdf
  734. #Jun 14 19:22:31 (none) user.notice kernel: sd 5:0:0:1: Attached scsi removable disk sdg
  735. #Jun 15 03:21:33 (none) user.notice kernel: sd 2:0:0:0: Attached scsi disk sda
  736.  
  737.  
  738.     set fid [open "/var/log/messages" r]
  739.     while {![eof $fid]} {
  740.         gets $fid str
  741.         set sl [remove_empties [split $str]]
  742.         if {[lindex $sl 4] == "user.info"} {
  743.             if {[lindex $sl 5] == "kernel:"} {
  744.                 #puts "[string range [lindex $sl 6] 0 3]"
  745.                 if {[string range [lindex $sl 6] 0 3] == "scsi"} {
  746.                     set n [string range [lindex $sl 6] 4 end]
  747.                     #puts "scsi$n has driver: [lrange $sl 8 end]"
  748.                     if {[join [lrange $sl 8 end]] == "SCSI emulation for USB Mass Storage devices"} {
  749.                         set ::scsi_drvr($n) "usb_storage"
  750.                     } else {
  751.                         set ::scsi_drvr($n) [lrange $sl 8 end]
  752.                     }
  753.                 }
  754.             }
  755.         }
  756.         if {[lindex $sl 6] == "sd"} {
  757.             if {[lindex $sl 8] == "Attached"} {
  758.                 if {[lindex $sl 9] == "scsi"} {
  759.                     if {[lindex $sl 10] == "removable"} {
  760.                         set n [lindex [split [lindex $sl 7] :] 0]
  761.                         #puts "scsi$n == [lindex $sl 12] "
  762.                         set ::scsi_node([lindex $sl 12]) $n
  763.                     }
  764.                     if {[lindex $sl 10] == "disk"} {
  765.                         set n [lindex [split [lindex $sl 7] :] 0]
  766.                         #puts "scsi$n == [lindex $sl 11] "
  767.                         set ::scsi_node([lindex $sl 11]) $n
  768.                     }
  769.                 }
  770.             }
  771.         }
  772.         
  773.     }
  774.     close $fid
  775. }
  776.  
  777. proc scsi_or_usb_grabinfos {} {
  778.     array unset ::scsi_N
  779.  
  780.     array unset scsi_ctrlr
  781.  
  782.     catch {
  783.         set fid [open "/proc/scsi/scsi" r]
  784.         set host_n ""
  785.         set vend ""
  786.         set modl ""
  787.         while {![eof $fid]} {
  788.             gets $fid str
  789.             set sl [remove_empties [split $str]]
  790.             if {[lindex $sl 0] == "Host:"} {
  791.                 set host_n [string map {scsi {}} [lindex $sl 1]]
  792.                 set scsi_ctrlr($host_n) "Present"
  793.             }
  794.             if {[lindex $sl 0] == "Vendor:"} {
  795.                 set m_at [lsearch $sl "Model:"]
  796.                 set r_at [lsearch $sl "Rev:"]
  797.                 set vend ""
  798.                 set modl ""
  799.                 if {0 != [expr $m_at-1]} {
  800.                     set vend [join [lrange $sl 1 [expr $m_at-1]]]
  801.                 }
  802.                 if {$m_at != [expr $r_at-1]} {
  803.                     set modl [join [lrange $sl [expr $m_at+1] [expr $r_at-1]]]
  804.                 }
  805.             }
  806.             if {[lindex $sl 0] == "Type:"} {
  807.                 set r_at [lsearch $sl "ANSI"]
  808.                 set type ""
  809.                 if {0 != [expr $m_at-1]} {
  810.                     set type [join [lrange $sl 1 [expr $r_at-1]]]
  811.                 }
  812.                 set ::scsi_N($host_n)  "$vend|$modl|$type"
  813.                 if {$::debug} { puts " ::scsi_N($host_n) = $vend|$modl|$type"}
  814.             }
  815.         }
  816.         close $fid
  817.     }
  818.     
  819.     catch {
  820.         foreach ctrlr [array names scsi_ctrlr] {
  821.             set hostis "scsi"
  822.             catch {
  823.                 if {[string match -nocase *usb* $::scsi_drvr($ctrlr)] == 1} {
  824.                     set hostis "usb"
  825.                 }
  826.             }
  827.             catch {
  828.                 set fid [open "/proc/scsi/usb-storage/$ctrlr" r]
  829.                 while {![eof $fid]} {
  830.                     gets $fid str
  831.                     set hostis "usb"
  832.                 }
  833.                 close $fid
  834.             }
  835.             
  836.             catch {
  837.                 if {[string match -nocase *sata* $::scsi_drvr($ctrlr)] == 1} {
  838.                     set hostis "sata"
  839.                 }
  840.             }
  841.             set vend [lindex [split $::scsi_N($ctrlr) |] 0]
  842.             if {$vend == "ATA"} { 
  843.                 set hostis "sata"
  844.             }
  845.             #puts "scsi$ctrlr Host is really $hostis"
  846.             set info $::scsi_N($ctrlr)
  847.             set ::scsi_N($ctrlr) "$hostis|$info"
  848.         }
  849.     }
  850. }
  851.  
  852.  
  853. proc mainDeviceList__derive {} {
  854.     set dev_list [lsort -dictionary [array names ::diskStats]]
  855. if {$::debug} {puts "$$ dev_list  $dev_list"}
  856.     set omit_parts "false"
  857.     foreach dev $dev_list {
  858.         
  859.         if {[string match "$omit_parts*" $dev] == 1} {
  860.             continue;
  861.         }
  862.         set omit_parts "false"
  863.         
  864.         set ds [split $::diskStats($dev) .]
  865.         set dev_type [lindex $ds 3]
  866.         set icon ""
  867.         set fs ""
  868.         set part ""
  869.         set mnt ""
  870.         set vol ""
  871.         set hw_name ""
  872.         set gui_cmds ""
  873.         catch {set part [lindex $::partitions($dev) 0] }
  874.         catch {set mnt [lindex [split $::mounteds(/dev/$dev) |] 0] }
  875.         catch {set fs [lindex [split $::mounteds(/dev/$dev) |] 1] }
  876.         if {$part == "extended"} { continue }
  877.         set noscan false
  878.         switch $dev_type {
  879.             floppy {
  880.                 set fdinfo ""
  881.                 catch " exec $::mut/bin/fdinfo /dev/$dev" fdinfo
  882.                 if {[llength [split $fdinfo |]]>3} {
  883.                     set fdx [lindex [split $fdinfo |] 1]
  884.                     if {$fdx != 5} { set fdx 3 }
  885.                     set icon "fd$fdx"
  886.                 }
  887.                 catch {
  888.                     if {$::NoScanMedia($dev)=="noscan"} { set noscan true }
  889.                 }
  890.             }
  891.             disk {
  892.                 set icon "disk"
  893.                 set noscan true
  894.                 if {[lindex $ds 2] == "sd" } {
  895.                     catch {
  896.                         set ctrlr $::scsi_node($dev)
  897.                         set ctrlr_info [split $::scsi_N($ctrlr) |]
  898.                         set hw_name [lindex $ctrlr_info 2]
  899.                         set icon "[lindex $ctrlr_info 0]disk"
  900.                         #set driver $::scsi_drvr($ctrlr)
  901.                     }                    
  902.                     
  903.             #Here We check for SuperFloppy format:
  904.                     if {$part != "extended"} {
  905.                         set fsinfo ""
  906.                         catch "exec $::mut/bin/guess_fstype /dev/$dev" fsinfo
  907.                         if {$fsinfo != ""} {set fs $fsinfo}
  908.                         if {[lindex [split $fsinfo] 0] == "unknown"} {set fs ""}
  909.                         if {$fs != ""} {
  910.                             set parts 0
  911.                             set unknownparts 0
  912.                             foreach d $dev_list {
  913.                                 if {[string match "$dev*" $d]==1} { 
  914.                                     if {$d != $dev} {
  915.                                         set fsinfo ""
  916.                                         catch "exec $::mut/bin/guess_fstype /dev/$d" fsinfo
  917.                                         if {$fsinfo == "unknown"} { incr unknownparts }
  918.                                         incr parts
  919.                                     }
  920.                                 }
  921.                             }
  922.                             if {$parts == $unknownparts} {
  923.                                 set noscan false
  924.                                 set dev_type superfloppy
  925.                                 set omit_parts "$dev"
  926.                             } else {
  927.                                 set fs ""
  928.                             }
  929.                         }
  930.                     }
  931.                 } else {
  932.                     if {[string range [lindex $ds 2] 0 2] == "ide" } {
  933.                         set hw_name [scan_ide_medium [lindex $ds 2] $dev model]
  934.                     }
  935.                 }
  936.             }
  937.             part {
  938.                 set icon "none"
  939.                 set noscan false
  940.                 if {$fs == "" && $part != "extended"} {
  941.                     set fsinfo ""
  942.                     catch "exec $::mut/bin/guess_fstype /dev/$dev" fsinfo
  943.                     if {$fsinfo != ""} {set fs $fsinfo}
  944.                 }
  945.             }
  946.             cdrom {
  947.                 set cdinfo [split $::cdromMedium($dev) |]
  948.                 set dt [lindex $cdinfo 1]
  949.                 set ty [lindex $cdinfo 2]
  950.                 set ok1 "false"; set ok2 "false"
  951.                 set noscan true
  952.                 if {$dt=="DVD"} {set dt dvd ; set ok2 true}
  953.                 if {$dt=="CD"} {set dt cd ; set ok2 true}
  954.                 if {$ty=="R&W"} {set ty raw ; set ok1 true}
  955.                 if {$ty=="RO"} {set ty ro ; set ok1 true}
  956.                 if {$ok1 && $ok2} {set icon "$dt$ty"} else {set icon "cdhuh"}
  957.                 if {[lindex $cdinfo 4]=="SW_CLOSE" && [lindex $cdinfo 6]== "open" } {
  958.                     lappend gui_cmds cd_tray_close
  959.                     if { $::Kernel_Version=="2.4" } {
  960.                         lappend gui_cmds cd_disc_eject
  961.                     }
  962.                 }
  963.  
  964.                 if {[lindex $cdinfo 5]=="SW_OPEN" && [lindex $cdinfo 6]== "closed"} {
  965.                     lappend gui_cmds cd_disc_eject
  966.                 }
  967.                 if {[lindex $cdinfo 7] == "Audio" || [lindex $cdinfo 7] == "Mixed"} { 
  968.                     if { [lindex $cdinfo 8] > 0 } {
  969.                         set fs [lindex $cdinfo 7]; set vol "[lindex $cdinfo 8] tracks" 
  970.                         lappend gui_cmds cd_play_audio
  971.                     }
  972.                 }
  973.                 if {[lindex $cdinfo 7] == "Data" || [lindex $cdinfo 7] == "Mixed"} {
  974.                     if {$dt=="dvd"} {lappend gui_cmds gxine_dvd_play}
  975.                     if { [lindex $cdinfo 9] > 0 } {
  976.                         set fs [lindex $cdinfo 7]; 
  977.                         set vol [grab_fs_vol iso9660 $dev]
  978.                         if {$mnt == ""} {lappend gui_cmds cd_disk_mount}
  979.                         if {$mnt != ""} {lappend gui_cmds cd_disk_unmount}
  980.                     }
  981.                 }
  982.                 if {[string range [lindex $ds 2] 0 2] == "ide" } {
  983.                     set hw_name [scan_ide_medium [lindex $ds 2] $dev model]
  984.                 }
  985.  
  986.             }
  987.             default { if {$::debug} {puts "Unknown device type $dev_type on $dev"} }
  988.         }
  989.         if {$fs=="" && $noscan==false && $part!="extended"} {
  990.             set fsinfo ""
  991.             catch "exec $::mut/bin/guess_fstype /dev/$dev" fsinfo
  992.             if {$fsinfo != ""} {set fs $fsinfo}
  993.             if {$fs == "unknown"} { set fs "" }
  994.         }
  995.  
  996.         if {$vol=="" && $noscan==false} {
  997.             if {$fs == "unknown"} { set fs "" }
  998.             if {$fs == "iso9660" && $vol==""} { set vol [grab_fs_vol iso9660 $dev] }
  999.             if {$fs == "vfat"} { set vol [grab_fs_vol vfat $dev] }
  1000.             if {$fs == "ext2"} { set vol [grab_fs_vol ext2 $dev] }
  1001.         }
  1002.         if {$dev_type == "floppy"} {
  1003.             if {$noscan} {
  1004.                 set part "unknown"
  1005.                 lappend gui_cmds scan
  1006.             } else {
  1007.                 lappend gui_cmds dev_part_info
  1008.                 if {$part == "" && $fs!=""} {
  1009.                     set part "Disc"
  1010.                     if {$mnt == ""} {
  1011.                         lappend gui_cmds dev_mount 
  1012.                     }
  1013.                 } else {
  1014.                     set part "No Disc"
  1015.                 }
  1016.                 lappend gui_cmds noscan
  1017.             }
  1018.             if {$mnt != ""} {
  1019.                 lappend gui_cmds dev_rox
  1020.                 if {[permit_unmount $mnt]} {
  1021.                     lappend gui_cmds dev_unmount
  1022.                 }
  1023.                 lappend gui_cmds dev_part_mnt
  1024.             }
  1025.         }
  1026.         if {$dev_type == "superfloppy"} {
  1027.             lappend gui_cmds dev_part_info
  1028.             if {$mnt == ""} {
  1029.                 lappend gui_cmds dev_mount 
  1030.             } else {
  1031.                 lappend gui_cmds dev_rox
  1032.                 if {[permit_unmount $mnt]} {
  1033.                     lappend gui_cmds dev_unmount
  1034.                 }
  1035.                 lappend gui_cmds dev_part_mnt
  1036.             }
  1037.         }
  1038.  
  1039.         if {$::debug} {puts "test  $dev|$icon|$hw_name|$part|$mnt|$fs|$vol|[join $gui_cmds ,]|$dev_type|" }
  1040.  
  1041.         if {$icon=="none" && ($part =="" || $fs=="") && $mnt == "" &&  $vol == "" && [llength $gui_cmds] ==0} {continue}
  1042.  
  1043.         if {[llength $gui_cmds] ==0 && [string length $dev]==3 && [llength [lsearch -all $dev_list $dev*]] == 1 } {continue}
  1044.         lappend ::infolist "$dev|$icon|$hw_name|$part|$mnt|$fs|$vol|[join $gui_cmds ,]|$dev_type|"
  1045.         if {$::debug} {puts "::infolist  [lindex $::infolist end]"}
  1046.     }
  1047. }
  1048.  
  1049. proc grab_block_devices {{quick false}} {
  1050.     majorBus__get_list
  1051.     partitions__get_list
  1052.     device_nodes__scan_for_make_additional
  1053.     diskStats__get_list quick
  1054.     cdromMedium_get_list quick
  1055.     etc_fstab__get_list
  1056.     mounteds__get_list
  1057.     scsi_host_to_sd_location 
  1058.     scsi_or_usb_grabinfos
  1059.     mainDeviceList__derive
  1060. }
  1061.  
  1062. proc run_full_scan {} {
  1063.     array unset ::partitions
  1064.     array unset ::mounteds
  1065.  
  1066.     #scan hardware
  1067.     grab_block_devices true
  1068. }
  1069.  
  1070. proc run_quick_update {} {
  1071.     array unset ::partitions
  1072.     array unset ::mounteds
  1073.  
  1074.     #scan hardware
  1075.     grab_block_devices
  1076.  
  1077. }
  1078.  
  1079. proc usb_autoscan {{how refresh}} {
  1080.     if {[file exists /proc/bus/usb/devices]} {
  1081.         if {$how == "on"} {
  1082.             if {$::debug} {puts "usb_autoscan $how"}
  1083.             full_refresh_display
  1084.             after 2000 usb_autoscan refresh2000
  1085.             set ::Program_Initialized true
  1086.             return
  1087.         }
  1088.         set hotplug [file mtime /proc/bus/usb/devices]
  1089.         if {$hotplug != $::last_hotplug} {
  1090.             if {$::debug} {puts "usb_autoscan $how now=$hotplug last=$::last_hotplug"}
  1091.             after 1000 full_refresh_display
  1092.             after 1500 usb_autoscan refresh1500
  1093.         } else {
  1094.             after 200 usb_autoscan refresh200
  1095.         }
  1096.     }
  1097. }
  1098.  
  1099. # we tend to get lots of window updates all in a row, so we skip all but last in a short time to update window.
  1100. # this saves on rattelling the floppy drive to bits :)
  1101. proc rearrange {{how Unknown}} {
  1102.     #puts [wm geometry .]
  1103.     if {$how == "config"} {
  1104.         incr ::Stack_rearrange
  1105.         if {$::debug} {puts "rearrange $how $::Stack_rearrange"}
  1106.         after 30 rearrange delayed
  1107.     }
  1108.     if {$how == "delayed"} {
  1109.         incr ::Stack_rearrange -1
  1110.         if {$::debug} {puts "rearrange $how $::Stack_rearrange"}
  1111.         if {$::Stack_rearrange == 0 && $::Program_Initialized == true} { full_refresh_display }
  1112.     }
  1113. }
  1114.  
  1115. proc Create_Display {} {
  1116.     wm title . "Media Utility Tool $::Version"
  1117.  
  1118.     frame .box 
  1119.  
  1120.     label .status_bar -text "MUT $::Version, written by Jesse Liley for Puppy Linux 2005."
  1121.     pack .status_bar -in . -side bottom -fill x
  1122.  
  1123.     canvas .boxc -width 180 -height 350 -bd 0 -bg gray50 -highlightthickness 0 
  1124.  
  1125.     pack .box -in . -fill both -expand yes
  1126.     pack .boxc -in .box -fill both -expand yes
  1127.  
  1128.     bind .boxc <Button-1> { check_click_action %x %y }
  1129.  
  1130.     # Mouse Wheel scrolling.
  1131.     # bind .boxc <Button-4> { .boxc yview scroll -3 units }
  1132.     # bind .boxc <Button-5> { .boxc yview scroll 3 units }
  1133.     
  1134.     
  1135.     bind . <Configure> "rearrange config"
  1136. }
  1137.  
  1138. proc set_box_trigger {itm dev y1 x1 width colour tex act} {
  1139.     upvar 1 $itm n
  1140.     set y2 [expr "11 + $y1"]
  1141.     set x2 [expr "$x1 + $width"]
  1142.     .boxc create rectangle $x1 $y1 $x2 $y2 -outline $colour
  1143.     .boxc create text [expr "$x1 + 4"] $y1 -anchor nw -text $tex -fill $colour -font {Helvetica -10 bold} 
  1144.     set ::actions($n) [list $act $x1 $y1 $x2 $y2 $dev]
  1145.     if {$::debug} {puts "actions($n) = [list $act $x1 $y1 $x2 $y2 $dev]" }
  1146.     incr n
  1147. }
  1148.  
  1149. proc max {a b} {
  1150.     if {$a > $b} {return $a}
  1151.     return $b
  1152. }
  1153.  
  1154. set ::clr(mount) "LightBlue"
  1155.  
  1156. proc Show_Devices {} {
  1157.     set index 1
  1158.     set n_itm 1
  1159.     set ypos 5
  1160.     set nextdev_ypos $ypos
  1161.     set start_horizontal_pos 50
  1162.  
  1163.     foreach str $::infolist {
  1164.         set l ".l$index"
  1165.         set info [split $str "|"]
  1166.         set xpos 110
  1167.  
  1168.         set dev [lindex $info 0]
  1169.         set icon [lindex $info 1]
  1170.         set hw_name [lindex $info 2]
  1171.         set part [lindex $info 3]
  1172.         set mnt [lindex $info 4]
  1173.         set fs [lindex $info 5]
  1174.         set vol [lindex $info 6]
  1175.         set guicmds [split [lindex $info 7] ,]
  1176.         set dev_type [lindex $info 8]
  1177.  
  1178.         if {$icon!="" && $icon!="none"} { # only devices have icons at this point
  1179.             set ypos [max $ypos $nextdev_ypos]
  1180.             set xpos 3
  1181.             set tex "$dev :: $hw_name"
  1182.             .boxc create image $xpos $ypos -anchor nw -image ::img::img($icon)
  1183.             set xpos [expr "$xpos + [image width ::img::img($icon)] + 3" ]
  1184.             .boxc create text $xpos $ypos -anchor nw -text $tex -fill White -font {Helvetica -10 bold }
  1185.             incr ypos 14
  1186.             incr xpos 5
  1187.  
  1188.             foreach cmd $guicmds {
  1189.                 switch $cmd {
  1190.                     gxine_dvd_play {
  1191.                         set_box_trigger n_itm $dev [expr "2 + $ypos"] $xpos 57 Cyan "GxineDVD" "gxinedvd"
  1192.                         incr xpos 57
  1193.                     }
  1194.                     dev_part_mnt {
  1195.                         if {$mnt != "" } {
  1196.                             .boxc create text $xpos [expr "$ypos + 4"] -anchor nw -text "$mnt" -fill $::clr(mount) -font {Courier -10 bold} 
  1197.                             incr xpos [expr " 7 * [string length $mnt]"]
  1198.                         }
  1199.                     }
  1200.                     dev_part_info {
  1201.                         set d [lindex [split $dev '/'] end]
  1202.                         set d [string trim $d "abcdefghijklmnopqrstuvwxyz/"]
  1203.                         set tex "[string toupper $d] $fs"
  1204.                         set v "$vol"
  1205.                         incr xpos 8
  1206.                         .boxc create text [expr "$xpos"] [expr "$ypos +4"] -anchor nw -text "$vol." -fill White -font {Courier -10  }
  1207.                         .boxc create text [expr "$xpos-8"] [expr "$ypos -3"] -anchor nw -text $tex -fill #dfdfdf -font {Courier -10  }
  1208.  
  1209.  
  1210.                         incr xpos [max [expr " 5 * [string length $tex]"] [expr "5+ 6 * [string length $v]"] ]
  1211.  
  1212.                         set tex "$fs:$part"
  1213.                         .boxc create text $xpos [expr "2 + $ypos"] -anchor nw -text "$part" -fill black -font {Helvetica -10 bold }
  1214.                         incr xpos [expr " 6 * [string length $part]"]
  1215.                     }
  1216.                     dev_rox {
  1217.                         set_box_trigger n_itm $dev [expr "2 + $ypos"] $xpos 25 LightGoldenrod "Rox" "rox"
  1218.                         incr xpos 25
  1219.                     }
  1220.                     dev_unmount {
  1221.                         set_box_trigger n_itm $dev [expr "2 + $ypos"] $xpos 50 PeachPuff "UnMount" "unmount"
  1222.                         incr xpos 50
  1223.                     }
  1224.                     dev_mount {
  1225.                         set_box_trigger n_itm $dev [expr "2 + $ypos"] $xpos 37 pink "Mount" "mount"
  1226.                         incr xpos 37
  1227.                     }
  1228.                     scan {
  1229.                         set_box_trigger n_itm $dev [expr "2 + $ypos"] $xpos 29 Yellow "Scan" "scan"
  1230.                         incr xpos 29
  1231.                     }
  1232.                     noscan {
  1233.                         set_box_trigger n_itm $dev [expr "2 + $ypos"] $xpos 43 Yellow "NoScan" "noscan"
  1234.                         incr xpos 43
  1235.                     }
  1236.                     cd_disk_mount {
  1237.                         set_box_trigger n_itm $dev [expr "2 + $ypos"] $xpos 37 pink "Mount" "cdmount"
  1238.                         incr xpos 37
  1239.                         if {$fs == "Mixed" || $fs=="Data"} {
  1240.                             incr xpos 5
  1241.                             .boxc create text $xpos [expr "2 + $ypos"] -anchor nw -text $vol -fill black -font {Helvetica -10 bold }
  1242.                             incr xpos 27
  1243.                         }
  1244.                     }
  1245.                     cd_disk_unmount {
  1246.                         incr xpos 5
  1247.                         set_box_trigger n_itm $dev [expr "2 + $ypos"] $xpos 25 LightGoldenrod "Rox" "rox"
  1248.                         incr xpos 25
  1249.                         incr xpos 5
  1250.                         set_box_trigger n_itm $dev [expr "2 + $ypos"] $xpos 50 PeachPuff "UnMount" "cdunmount"
  1251.                         incr xpos 50
  1252.                         if {$fs == "Mixed" || $fs=="Data"} {
  1253.                             incr xpos 6
  1254.                             .boxc create text $xpos [expr "2 + $ypos"] -anchor nw -text $vol -fill black -font {Helvetica -10 bold }
  1255.                             incr xpos [expr " 7 * [string length $vol] + 4"]
  1256.  
  1257.                             incr xpos 5
  1258.                             .boxc create text $xpos [expr "2 + $ypos"] -anchor nw -text "$mnt" -fill $::clr(mount) -font {Courier -10 bold}
  1259.                             incr xpos [expr " 7 * [string length $mnt]"]
  1260.                         }
  1261.                     }
  1262.                     cd_play_audio {
  1263.                         incr xpos 6
  1264.                         set_box_trigger n_itm $dev [expr "2 + $ypos"] $xpos 56 cyan "CD Player" "cdplay"
  1265.                         incr xpos 56
  1266.                     }
  1267.                     cd_disc_eject {
  1268.                         incr xpos 6
  1269.                         set_box_trigger n_itm $dev [expr "2 + $ypos"] $xpos 30 SpringGreen "Eject" "eject"
  1270.                         incr xpos 30
  1271.  
  1272.                         incr xpos 6
  1273.                         .boxc create text $xpos [expr "2 + $ypos"] -anchor nw -text $fs -fill black -font {Helvetica -10 bold }
  1274.                         incr xpos 25
  1275.                     }
  1276.                     cd_tray_close {
  1277.                         incr xpos 6
  1278.                         set_box_trigger n_itm $dev [expr "2 + $ypos"] $xpos 35 tan "Close" "trayclose"
  1279.                         incr xpos 35
  1280.                     }
  1281.                     default { if {$::debug} {puts "Unhandled cmd $cmd"} }
  1282.                 }
  1283.                 incr xpos 4
  1284.             }
  1285.             set nextdev_ypos [expr "26 + $ypos"]
  1286.         }
  1287.  
  1288.         set xpos $start_horizontal_pos
  1289.  
  1290.         if { $dev_type == "part" } {
  1291.             set d [lindex [split $dev '/'] end]
  1292.             set d [string trim $d "abcdefghijklmnopqrstuvwxyz/"]
  1293.             set tex "[string toupper $d] $fs"
  1294.  
  1295.             .boxc create text [expr "$xpos"] [expr "$ypos +4"] -anchor nw -text "$vol." -fill White -font {Courier -10  }
  1296.             .boxc create text [expr "$xpos-8"] [expr "$ypos -3"] -anchor nw -text $tex -fill #dfdfdf -font {Courier -10  }
  1297.             incr xpos 120
  1298.             .boxc create text $xpos $ypos -anchor ne -text $part -font {Helvetica -10}
  1299.  
  1300.             if {$mnt != "" && $fs != "Audio"} {
  1301.                 if {$mnt != "" && $fs != "swap" && $fs != "initrdswap"} {
  1302.                     incr xpos 5
  1303.                     set_box_trigger n_itm $dev $ypos $xpos 26 LightGoldenrod "Rox" "rox"
  1304.                     incr xpos 26
  1305.                 }
  1306.                 if {$mnt != ""} {
  1307.                     if {$fs != "swap" && $fs != "initrdswap" &&[permit_unmount $mnt]} {
  1308.                         incr xpos 5
  1309.                         set_box_trigger n_itm $dev $ypos $xpos 49 PeachPuff "Unmount" "unmount"
  1310.                         incr xpos 49
  1311.                     }
  1312.                     incr xpos 5
  1313.                     .boxc create text $xpos [expr "2 + $ypos"] -anchor nw -text "$mnt" -fill $::clr(mount) -font {Courier -10 bold} 
  1314.                     incr xpos [expr " 7 * [string length $mnt]"]
  1315.                 }
  1316.                 if {$fs == "swap"} {
  1317.                     incr xpos 5
  1318.                     set_box_trigger n_itm $dev $ypos $xpos 51 blue "Swap Off" "swapoff"
  1319.                     incr xpos 51
  1320.                 }
  1321.                 if {$fs == "initrdswap"} {
  1322.                     incr xpos 5
  1323.                     set_box_trigger n_itm $dev $ypos $xpos 51 blue "Swap Off" "initrdswapoff"
  1324.                     incr xpos 51
  1325.                 }
  1326.             } elseif { $fs == "Audio" } {
  1327.  
  1328.             } elseif { $fs != "" && $fs != "unknown" && $part != ""} {
  1329.                 if { $fs == "swap" } {
  1330.                     incr xpos 5
  1331.                     set_box_trigger n_itm $dev $ypos $xpos 56 SkyBlue "Use Swap" "swapon"
  1332.                     incr xpos 56
  1333.                 } else {
  1334.                     if {$mnt == ""} {
  1335.                         incr xpos 5
  1336.                         set_box_trigger n_itm $dev $ypos $xpos 37 pink "Mount" "mount"
  1337.                         incr xpos 37
  1338.                     }
  1339.                 }
  1340.             }
  1341.             incr ypos 19
  1342.             set nextdev_ypos [max [expr "10 + $ypos"] $nextdev_ypos]
  1343.         }
  1344.         incr index
  1345.     }
  1346.  
  1347. }
  1348.  
  1349.  
  1350.  
  1351. ## Initialise global variables here:
  1352.  
  1353. set Version "0.0.9b";                      # Version Number
  1354. set mut [homepath];                       # Home path to app directory, Now done automatically! :-)
  1355. set debug 0;                              # Choose output of debugging information, output is to stdout
  1356. set last_hotplug 0;                       # USB SCSI hotplug last refresh info, for hot [un]plug scanning.
  1357. set Kernel_Version ""
  1358. set Program_Initialized false;            # Make start quicker.
  1359.  
  1360. # get the Kernel version.
  1361. proc get_kv {} {
  1362.     set ::Kernel_Version "Unknown"
  1363.     catch {
  1364.         set fid [open "/proc/version" r]
  1365.         while {![eof $fid]} {
  1366.             gets $fid str
  1367.             set ::Kernel_Version "[string range [lindex [split $str] 2] 0 2]"
  1368.             break;
  1369.         }
  1370.         close $fid
  1371.     }
  1372. }
  1373. get_kv
  1374.  
  1375. ## global variables used to describe attached hardware:
  1376.  
  1377.  
  1378. array unset partitions ;                  # List of info from /proc/partitions
  1379. array unset mounteds ;                    # List of info from /proc/mounts
  1380. array unset actions ;                     # "click actions" value is a list of {action minx miny maxx maxy}
  1381. set Stack_rearrange 0 ;                   # Stack the window rearrange events
  1382. array unset etc_fstab ;                   # save info from /etc/fstab file.
  1383. array unset cdromMedium ;                 # List of info from bin/cdrominfo about cdrom drives in system
  1384. array unset diskStats ;                   # info about block devices in system
  1385. set grabdevs {fd hd sd scd sr} ;          # list of device types to scan in /proc/diskstats & /proc/partitions
  1386. set existing_nodes "" ;                   # Keep track of nodes that exist in /dev directory.
  1387. array unset majorBus ;                    # block device info from /proc/devices
  1388. array unset majorBusRev ;                 # reverse lookup of majorBus, not always best to use! heh :)
  1389. set infolist "";                          # The list of displayed devices & partitions.
  1390.  
  1391. ## Process command line arguments, debuging flag only at this point
  1392.  
  1393. if {$argc > 0} {
  1394.     for {set i 0} {$i < $argc} {incr i} {
  1395.         set sw [string trimleft [lindex $argv $i] "- "]
  1396.         switch $sw {
  1397.             "d" {set debug 1 ; puts "debugging on"}
  1398.             "debug" {set debug 1 ; puts "debugging on"}
  1399.             default {}
  1400.         }
  1401.     }
  1402. }
  1403.  
  1404. ## Load Images for display:
  1405. image create photo ::img::img(fd3)     -file "$mut/icon/fd3.ppm"
  1406. image create photo ::img::img(fd5)     -file "$mut/icon/fd5.ppm"
  1407. image create photo ::img::img(cdhuh)   -file "$mut/icon/cdhuh.ppm"
  1408. image create photo ::img::img(cdro)    -file "$mut/icon/cd-ro.ppm"
  1409. image create photo ::img::img(cdraw)   -file "$mut/icon/cd-raw.ppm"
  1410. image create photo ::img::img(dvdro)   -file "$mut/icon/dvd-ro.ppm"
  1411. image create photo ::img::img(dvdraw)  -file "$mut/icon/dvd-raw.ppm"
  1412. image create photo ::img::img(disk)    -file "$mut/icon/disk.ppm"
  1413. image create photo ::img::img(scsidisk) -file "$mut/icon/scsidisk.ppm"
  1414. image create photo ::img::img(satadisk) -file "$mut/icon/satadisk.ppm"
  1415. image create photo ::img::img(usbdisk) -file "$mut/icon/usbdisk.ppm"
  1416. image create photo ::img::img(zip)     -file "$mut/icon/zip.ppm"
  1417. ## These two images are the screen tattoos
  1418. image create photo ::img::img(refresh) -file "$mut/icon/refresh.ppm"
  1419. image create photo ::img::img(tux)     -file "$mut/icon/tux.ppm"
  1420.  
  1421.  
  1422. # set transparency on tattoos
  1423. catch {
  1424.         foreach img [list "tux" "refresh"] {
  1425.         set width [image width ::img::img($img)]
  1426.         set height [image height ::img::img($img)]
  1427.         for {set x 0} {$x < $width} {incr x} {
  1428.             for {set y 0} {$y < $height} {incr y} {
  1429.                 #set c [lindex $data [incr ndx]]
  1430.                 set c [::img::img($img) get $x $y ]
  1431.                 if {[lindex $c 0] == 127 && [lindex $c 1] == 127 && [lindex $c 2] == 127} { 
  1432.                     ::img::img($img) transparency set $x $y 1
  1433.                 }
  1434.             }
  1435.         }
  1436.     }
  1437. }
  1438.  
  1439.  
  1440. ## MUT version information
  1441.  
  1442. if {$debug} {puts "'MUT version $::Version' on a $::Kernel_Version kernel, bugs, fixes, suggestions, email: Jesse.Liley@gmail.com"}
  1443. if {$::debug} { puts " unmountables are $NoUnmounts $PuppyNoUnmount"}
  1444. proc kick_off_autoscan {} {
  1445.     if {[file exists /proc/bus/usb/devices]} {
  1446.         usb_autoscan on
  1447.     } else {
  1448.         full_refresh_display
  1449.     }
  1450. }
  1451.  
  1452. ## Kick off the application, get it running:
  1453.  
  1454. catch { exec $mut/bin/load_drivers.sh }
  1455. Create_Display
  1456. after 2500 kick_off_autoscan
  1457. if {$debug} {puts "Program started"}
  1458.