forked from hummypkg/webif
848 lines
18 KiB
Tcl
848 lines
18 KiB
Tcl
|
|
source /mod/webif/lib/setup
|
|
|
|
package require xconv
|
|
|
|
if {![exists -proc class]} { package require oo }
|
|
if {![exists -proc sqlite3.open]} { package require sqlite3 }
|
|
if {![exists -proc binary]} { package require binary }
|
|
|
|
class system {}
|
|
|
|
proc {system model} {} {{model ""}} {
|
|
if {$model ne ""} { return $model }
|
|
if {[catch {set fp [open /etc/model r]}]} {
|
|
set model {HD[R]}
|
|
} else {
|
|
set model [string trim [read $fp]]
|
|
close $fp
|
|
}
|
|
return $model
|
|
}
|
|
|
|
proc {system hostname} {} {
|
|
if {[catch {set hostname [string trim [exec hostname]]}]} {
|
|
set hostname "humax"
|
|
}
|
|
return $hostname
|
|
}
|
|
|
|
proc {system ip} {} {
|
|
if {[catch {set fp [open /etc/hosts r]}]} {
|
|
set ip "127.0.0.1"
|
|
} else {
|
|
set ipl [lindex [split [$fp read] "\n"] 1]
|
|
regsub -- {[[:space:]].*} $ipl "" ip
|
|
$fp close
|
|
}
|
|
return $ip
|
|
}
|
|
|
|
proc {system modversion} {{short 0}} {{modver ""}} {
|
|
if {$modver eq ""} {
|
|
if {[catch {set fp [open /etc/modversion r]}]} {
|
|
set modver "102"
|
|
} else {
|
|
set modver [string trim [read $fp]]
|
|
close $fp
|
|
}
|
|
}
|
|
if {$short} { return $modver }
|
|
lassign [split $modver ""] a b c
|
|
return [format "%d.%d%d" $a $b $c]
|
|
}
|
|
|
|
proc {system modbuild} {} {{modbuild ""}} {
|
|
if {$modbuild ne ""} { return $modbuild }
|
|
if {[catch {set modbuild [string trim [file read /etc/modbuild]]}]} {
|
|
set modbuild 0
|
|
}
|
|
return $modbuild
|
|
}
|
|
|
|
proc {system lastbootreason} {{descr 1}} {{lbr -1}} {
|
|
if {$lbr == -1} {
|
|
set lbr 0
|
|
if {[file readable /tmp/.lbr]} {
|
|
set lbr [file read /tmp/.lbr]
|
|
}
|
|
}
|
|
if {!$descr} { return $lbr }
|
|
switch $lbr {
|
|
1 { return "Front panel button" }
|
|
2 { return "Remote control handset" }
|
|
3 { return "Scheduled event" }
|
|
}
|
|
return "Unknown ($lbr)"
|
|
}
|
|
|
|
proc {system idletime} {} {
|
|
if {[file exists "/tmp/.lastir"]} {
|
|
return $([clock seconds] - [file mtime "/tmp/.lastir"])
|
|
}
|
|
return 0
|
|
}
|
|
|
|
proc {system fhtcpversion} {} {{ver ""}} {
|
|
if {$ver ne ""} { return $ver }
|
|
set file "/etc/fhtcpversion"
|
|
if {![file exists $file]} { set file "/root/fhtcpversion" }
|
|
if {[catch {set fp [open $file r]}]} {
|
|
set ver "?.??.??"
|
|
} else {
|
|
set ver [string trim [read $fp]]
|
|
close $fp
|
|
}
|
|
return $ver
|
|
}
|
|
|
|
# :c0400 System ID
|
|
# 4:c8400 read 1128 bytes
|
|
# 3:c8c00 MAC address
|
|
# 2:c9000
|
|
# 1:cb400 DTCP key material
|
|
# 0:cb800 Serial Number
|
|
# 5:cbc00
|
|
|
|
proc {system systemid} {} {{id ""}} {
|
|
if {$id ne ""} { return $id }
|
|
set fd [open /dev/mtd3 r]
|
|
|
|
$fd seek 0xc0400
|
|
set bytes [$fd read 4]
|
|
$fd close
|
|
binary scan $bytes H* hex
|
|
set id [format "%s.%s" [string range $hex 0 3] [string range $hex 4 end]]
|
|
return $id
|
|
}
|
|
|
|
proc {system macaddr} {} {{mac ""}} {
|
|
if {$mac ne ""} { return $mac }
|
|
set fd [open /dev/mtd3 r]
|
|
|
|
$fd seek 0xc8c00
|
|
set bytes [$fd read 6]
|
|
$fd close
|
|
set tmac ""
|
|
foreach b [split $bytes ""] {
|
|
binary scan $b H* hex
|
|
if {$tmac ne ""} { append tmac : }
|
|
append tmac $hex
|
|
}
|
|
return [set mac $tmac]
|
|
}
|
|
|
|
proc {system serialno} {} {{serial ""}} {
|
|
if {$serial ne ""} { return $serial }
|
|
set fd [open /dev/mtd3 r]
|
|
|
|
$fd seek 0xcb800
|
|
set bytes [$fd read 14]
|
|
$fd close
|
|
set serial "[string range $bytes 0 1] [string range $bytes 2 8] [
|
|
string range $bytes 9 end]"
|
|
return $serial
|
|
}
|
|
|
|
proc {system encryptionkey} {} {{key ""}} {
|
|
if {$key ne ""} { return $key }
|
|
set fd [open /dev/mtd3 r]
|
|
$fd seek 0xc8c00
|
|
set bytes [$fd read 6]
|
|
$fd seek 0xcb800
|
|
append bytes [$fd read 10]
|
|
$fd close
|
|
binary scan $bytes H* key
|
|
return $key
|
|
}
|
|
|
|
proc {system loaderver} {} {{ver ""}} {
|
|
if {$ver ne ""} { return $ver }
|
|
set fd [open /dev/mtd3 r]
|
|
$fd seek 0x20006
|
|
set bytes [$fd read 2]
|
|
$fd close
|
|
set ver [switch $bytes {
|
|
"\x04\x5f" { format "a7.30" }
|
|
"\xec\xe5" { format "a7.31" }
|
|
"\x59\x9d" { format "a7.33" }
|
|
"\x72\x5c" { format "a7.34" }
|
|
"\xe5\xe3" { format "L7.26" }
|
|
"\x8f\x7c" { format "L7.27" }
|
|
default {
|
|
binary scan $bytes H* hex
|
|
format "Unknown - $hex"
|
|
}
|
|
}]
|
|
return $ver
|
|
}
|
|
|
|
proc {system kernelver} {} {{ver ""}} {
|
|
if {$ver ne ""} { return $ver }
|
|
#1 SMP Sun Mar 25 18:30:38 KST 2012
|
|
set rver [string range [exec uname -v] 11 end]
|
|
set ver [switch $rver {
|
|
# HDR
|
|
"Sep 16 20:17:56 KST 2010" { format "HDR_1.01.05" }
|
|
"Oct 11 21:11:05 KST 2010" { format "HDR_1.01.09" }
|
|
"Jan 21 15:44:39 KST 2011" { format "HDR_1.02.07" }
|
|
"Jun 11 00:54:19 KST 2011" { format "HDR_1.02.20" }
|
|
"Mar 25 18:30:38 KST 2012" { format "HDR_1.02.27" }
|
|
"May 27 00:19:34 KST 2012" { format "HDR_1.02.28" }
|
|
"Jul 5 11:11:28 KST 2012" { format "HDR_1.02.29" }
|
|
"Jan 12 16:49:05 KST 2013" { format "HDR_1.02.32" }
|
|
"Mar 6 07:27:02 KST 2013" { format "HDR_1.03.06(a)" }
|
|
"May 8 14:32:30 KST 2013" { format "HDR_1.03.06(b)" }
|
|
"Dec 10 14:36:54 KST 2013" { format "HDR_1.03.11" }
|
|
"Feb 7 14:15:02 KST 2014" { format "HDR_1.03.12" }
|
|
"May 19 22:39:27 BST 2014" { format "HDR_CFW_3.00" }
|
|
"Feb 19 20:58:57 GMT 2015" { format "HDR_CFW_3.03" }
|
|
"Mar 11 23:34:27 GMT 2016" { format "HDR_CFW_3.10" }
|
|
"Mar 11 23:37:22 GMT 2016" { format "HDR_CFW_3.10d" }
|
|
"Jan 9 04:46:49 GMT 2017" { format "HDR_CFW_3.11" }
|
|
"Jan 9 04:50:13 GMT 2017" { format "HDR_CFW_3.11d" }
|
|
"Mar 23 19:36:14 GMT 2017" { format "HDR_CFW_3.12" }
|
|
"Mar 23 19:39:44 GMT 2017" { format "HDR_CFW_3.12d" }
|
|
"Apr 18 22:42:30 BST 2017" { format "HDR_CFW_3.13" }
|
|
"Apr 18 22:45:34 BST 2017" { format "HDR_CFW_3.13d" }
|
|
|
|
# HD
|
|
"Oct 11 21:14:31 KST 2010" { format "HD_1.01.12" }
|
|
"May 17 14:16:20 KST 2011" { format "HD_1.02.18" }
|
|
"Jun 11 00:54:19 KST 2011" { format "HD_1.02.20" }
|
|
"Mar 25 07:09:19 KST 2012" { format "HD_1.02.27" }
|
|
"May 27 00:19:40 KST 2012" { format "HD_1.02.28" }
|
|
"Jul 5 19:41:17 KST 2012" { format "HD_1.02.29" }
|
|
"Oct 13 12:48:09 KST 2012" { format "HD_1.02.31" }
|
|
"Dec 9 14:15:07 KST 2014" { format "HD_1.03.02" }
|
|
|
|
default { format "Unknown - $rver" }
|
|
}]
|
|
return $ver
|
|
}
|
|
|
|
# Newer version below is over 100 times faster
|
|
#proc {system pkgver} {{pkg webif}} {
|
|
# return [lrange [split [exec opkg list-installed $pkg] " "] 2 end]
|
|
#}
|
|
|
|
proc {system pkgver} {{pkg webif}} {
|
|
if {[catch {set fp [open /mod/var/opkg/info/$pkg.control r]}]} {
|
|
return 0
|
|
}
|
|
|
|
set v 0
|
|
foreach line [split [$fp read] "\n"] {
|
|
if {[string equal -length 9 $line "Version: "]} {
|
|
lassign $line x v
|
|
break
|
|
}
|
|
}
|
|
$fp close
|
|
return $v
|
|
}
|
|
|
|
proc {system pkginst} {pkg} {
|
|
return [file exists "/mod/var/opkg/info/$pkg.control"]
|
|
}
|
|
|
|
proc {system mediaroot} {} {
|
|
switch [system model] {
|
|
HDR { return "/media/My Video" }
|
|
HD { return "/media/drive1/Video" }
|
|
}
|
|
return ""
|
|
}
|
|
|
|
proc {system dlnastatus} {} {
|
|
return [system is_listening 9000]
|
|
}
|
|
|
|
proc {system dlnadb} {} {
|
|
switch [system model] {
|
|
HDR { return "/mnt/hd2/dms_cds.db" }
|
|
HD { return "/media/drive1/dms_cds.db" }
|
|
}
|
|
return ""
|
|
}
|
|
|
|
proc {system _dlnaurl} {file urlbase} {
|
|
set mime "video/ts"
|
|
if {[catch {set db [sqlite3.open [system dlnadb]]}]} {
|
|
return {}
|
|
}
|
|
set muri [$db query {
|
|
select tblresource.mimetype, contenturi
|
|
from tblresource join tblmedia using (mediaid)
|
|
where localurl = '%s'} $file]
|
|
if {[llength $muri]} {
|
|
lassign [lindex $muri 0] x mime x xuri
|
|
} else {
|
|
# Try for partially linked entry
|
|
set muri [$db query {
|
|
select mediaid from tblmedia
|
|
where localurl = '%s'
|
|
} $file]
|
|
if {![llength $muri]} { return {} }
|
|
lassign [lindex $muri 0] x mediaid
|
|
set xuri "media/$mediaid.TS"
|
|
}
|
|
|
|
$db close
|
|
|
|
set url "http://${urlbase}:9000/web/$xuri"
|
|
|
|
return [list $url $mime]
|
|
}
|
|
|
|
proc {system dlnaurl} {file {urlbase ""}} {
|
|
if {$urlbase eq ""} { set urlbase [system ip] }
|
|
set retries 5
|
|
set ret {}
|
|
while {$retries > 0 && [\
|
|
catch {set ret [system _dlnaurl $file $urlbase]}]} {
|
|
incr retries -1
|
|
sleep 1
|
|
}
|
|
return $ret
|
|
}
|
|
|
|
proc {system dlnahelper} {file {urlbase ""}} {
|
|
set dir /mnt/hd2/mod/.dlnahelper
|
|
require lock
|
|
|
|
if {$file eq "-release"} {
|
|
release_lock dlnahelper
|
|
return {}
|
|
}
|
|
|
|
if {![acquire_lock dlnahelper 2]} { return {} }
|
|
|
|
if {![file isdirectory $dir]} { file mkdir $dir }
|
|
|
|
set base [file rootname $file]
|
|
foreach ext {hmt ts} {
|
|
file delete "$dir/helper.$ext"
|
|
file link -symbolic "$dir/helper.$ext" "$base.$ext"
|
|
}
|
|
|
|
set ret [system dlnaurl "$dir/helper.ts" $urlbase]
|
|
if {![llength $ret]} {
|
|
# Manually import the helper file.
|
|
if {![catch {set db [sqlite3.open [system dlnadb]]}]} {
|
|
$db query {
|
|
insert into tblmedia
|
|
(localurl,folder,mediatype,refcount)
|
|
values('%s','%s',0,1)
|
|
} "$dir/helper.ts" $dir
|
|
$db close
|
|
set ret [system dlnaurl "$dir/helper.ts" $urlbase]
|
|
}
|
|
}
|
|
if {![llength $ret]} {
|
|
release_lock dlnahelper
|
|
}
|
|
return $ret
|
|
}
|
|
|
|
proc {system dustbin} {{short 0}} {
|
|
set dustbin "\[Deleted Items\]"
|
|
if {![catch {set fd [open "/mod/boot/dustbin.name" r]}]} {
|
|
set dustbin [lindex [split [read $fd] "\n"] 0]
|
|
$fd close
|
|
}
|
|
if {$short} { return $dustbin }
|
|
return "[system mediaroot]/$dustbin"
|
|
}
|
|
|
|
proc {system dustbinsize} {} {
|
|
set bin [system dustbin]
|
|
set ret 0
|
|
if {[file isdirectory $bin]} {
|
|
if {[catch {
|
|
lassign [exec /mod/bin/busybox/du -s $bin] ret
|
|
}]} {
|
|
set ret 0
|
|
}
|
|
}
|
|
return $($ret * 1024)
|
|
}
|
|
|
|
proc {system diskpart} {} {
|
|
switch [system model] {
|
|
HDR { return "/mnt/hd2" }
|
|
HD { return "/media/drive1" }
|
|
}
|
|
return ""
|
|
}
|
|
|
|
proc {system diskdev} {} {
|
|
return [lindex [lsearch -regexp -inline \
|
|
[split [file read /proc/mounts] "\n\r"] " [system diskpart] "] 0]
|
|
}
|
|
|
|
proc {system disk} {} {
|
|
return [string range [system diskdev] 0 end-1]
|
|
}
|
|
|
|
proc {system disktemp} {} {
|
|
if {[catch {
|
|
set smart [exec /bin/smartctl -A [system disk] | grep ^194]
|
|
regsub -all -- {[[:space:]]+} $smart " " smart
|
|
set temp [lindex [split $smart] 9]
|
|
}]} {
|
|
set temp 0
|
|
}
|
|
return $($temp + 0)
|
|
}
|
|
|
|
require pretty_size
|
|
|
|
proc {system diskspace} {{raw 0}} {
|
|
set part [system diskpart]
|
|
|
|
lassign [exec /mod/bin/busybox/stat -f -c {%S %b %f} $part] \
|
|
bsize blocks fblocks
|
|
|
|
set size $($bsize * $blocks)
|
|
set free $($bsize * $fblocks)
|
|
set used $($size - $free)
|
|
set perc $($used * 100 / $size)
|
|
set fperc $(100 - $perc)
|
|
|
|
switch [system model] {
|
|
HDR {
|
|
set tsrdir "/mnt/hd2/Tsr"
|
|
set tsrok [file isdirectory $tsrdir]
|
|
}
|
|
HD {
|
|
set tsrdir "/media/drive1/.tsr"
|
|
set tsrok [file exists "$tsrdir/0.ts"]
|
|
}
|
|
}
|
|
|
|
if {$tsrok} {
|
|
set tsrbuf 21474836480
|
|
if {[catch {
|
|
lassign [exec du -ks $tsrdir] tsrused
|
|
}]} {
|
|
set tsrused 0
|
|
set tsrbuf 0
|
|
} else {
|
|
set tsrused $($tsrused * 1024)
|
|
}
|
|
} else {
|
|
set tsrbuf 0
|
|
set tsrused 0
|
|
}
|
|
|
|
if {!$raw} {
|
|
set size [pretty_size $size]
|
|
set free [pretty_size $free]
|
|
set used [pretty_size $used]
|
|
set tsrbuf [pretty_size $tsrbuf]
|
|
set tsrused [pretty_size $tsrused]
|
|
}
|
|
|
|
return [list $size $used $perc $free $fperc $tsrbuf $tsrused]
|
|
}
|
|
|
|
proc {system diskfree} {} {
|
|
lassign [exec /mod/bin/busybox/stat -f -c {%S %f} [system diskpart]] \
|
|
bsize fblocks
|
|
return $($bsize * $fblocks)
|
|
}
|
|
|
|
proc {system busy} {} {
|
|
# Is humaxtv doing anything important?
|
|
if {[catch {set pid [exec /mod/bin/busybox/pgrep -n humaxtv]}]} {
|
|
return 0
|
|
}
|
|
set c 0
|
|
foreach line [split [\
|
|
exec /mod/webif/lib/bin/lsof -X -Fn -p $pid] "\n"] {
|
|
if {[string match {*Video*.ts} $line]} { incr c }
|
|
}
|
|
if {$c > 0} { return 1 }
|
|
return 0
|
|
}
|
|
|
|
proc {system inuse} {file} {
|
|
if {![file exists $file]} { return 0 }
|
|
set op [exec /mod/webif/lib/bin/lsof -X -Fn $file]
|
|
switch -glob -- $op {
|
|
"" -
|
|
"*status error*" { return 0 }
|
|
}
|
|
return 1
|
|
}
|
|
|
|
proc {system dirinuse} {dir} {
|
|
set files {}
|
|
foreach line [split [\
|
|
exec /mod/webif/lib/bin/lsof -X -Fn +d $dir] "\n"] {
|
|
if {[string index $line 0] ne "n"} continue
|
|
lappend files [file tail $line]
|
|
}
|
|
return $files
|
|
}
|
|
|
|
proc {system reboot} {{fast 0}} {
|
|
if {$fast} {
|
|
exec /mod/webif/lib/bin/reboot -f
|
|
} else {
|
|
exec /mod/webif/lib/bin/reboot
|
|
}
|
|
}
|
|
|
|
proc {system restartpending} {{mode 1}} {
|
|
if {$mode} {
|
|
close [open /tmp/.restartpending w]
|
|
} else {
|
|
file delete /tmp/.restartpending
|
|
}
|
|
}
|
|
|
|
proc {system param} {param {type Value} {tbl MENUCONFIG}} {
|
|
if {[catch {set db [sqlite3.open /var/lib/humaxtv/setup.db]} msg]} {
|
|
return 0
|
|
}
|
|
set val 0
|
|
set ret [$db query "
|
|
select item$type
|
|
from TBL_$tbl
|
|
where itemName = '$param'
|
|
"]
|
|
if {[llength $ret] == 1} {
|
|
lassign [lindex $ret 0] x val
|
|
}
|
|
$db close
|
|
return $val
|
|
}
|
|
|
|
proc {system padding} {} {
|
|
return [list \
|
|
[system param START_PADDING_TIME] \
|
|
[system param STOP_PADDING_TIME] \
|
|
]
|
|
}
|
|
|
|
proc {system instandby} {} {
|
|
return [system param LAST_STANDBY Value USERCONFIG]
|
|
}
|
|
|
|
proc {system mkdir_p} {dir} {
|
|
exec /mod/bin/busybox/mkdir -p $dir
|
|
}
|
|
|
|
proc {system dirblockers} {dir {permitted {".*"}}} {
|
|
set fl {}
|
|
foreach e [readdir -nocomplain $dir] {
|
|
if {$e in {. ..}} continue
|
|
if {[file isdirectory "$dir/$e"]} {
|
|
lappend fl $e
|
|
continue
|
|
}
|
|
set flag 1
|
|
foreach p $permitted {
|
|
if {[string match -nocase $p $e]} {
|
|
set flag 0
|
|
break
|
|
}
|
|
}
|
|
if {$flag} {
|
|
lappend fl $e
|
|
}
|
|
}
|
|
return $fl
|
|
}
|
|
|
|
proc {system rmdir_if_empty} {dir {permitted {".*"}}} {
|
|
set fl [system dirblockers $dir $permitted]
|
|
|
|
if {![llength $fl]} {
|
|
file delete -force $dir
|
|
return 1
|
|
}
|
|
return 0
|
|
}
|
|
|
|
proc {system listening} {{mport 0}} {
|
|
set ret {}
|
|
foreach line [split [exec /mod/bin/busybox/netstat -lntpw] "\n"] {
|
|
# Remove repeated spaces
|
|
regsub -all -- {[[:space:]]+} $line " " line
|
|
# tcp 0 0 0.0.0.0:9955 0.0.0.0:* LISTEN 169/humaxtv
|
|
lassign [split $line " "] x x x port x type app
|
|
if {$type ne "LISTEN"} { continue }
|
|
lassign [split $port ":"] x port
|
|
|
|
if {$mport && $mport != $port} { continue }
|
|
lappend ret [list $port [split $app "/"]]
|
|
}
|
|
return $ret
|
|
}
|
|
|
|
proc {system is_listening} {mport} {
|
|
return [llength [system listening $mport]]
|
|
}
|
|
|
|
proc {system logtimestamp} {} {
|
|
return [clock format [clock seconds] -format "%d/%m/%Y %H:%M:%S"]
|
|
}
|
|
|
|
proc {system _log} {log msg} {
|
|
set logfd [open $log "a+"]
|
|
puts $logfd "[system logtimestamp] - $msg"
|
|
$logfd close
|
|
}
|
|
|
|
proc {system log} {log msg} {
|
|
system _log "/var/log/$log.log" $msg
|
|
}
|
|
|
|
proc {system plog} {log msg} {
|
|
system _log "/mod/tmp/$log.log" $msg
|
|
}
|
|
|
|
proc {system notify} {msg} {
|
|
system plog notify $msg
|
|
}
|
|
|
|
proc {system display} {hdr hd} {
|
|
if {[system model] eq "HDR"} {
|
|
exec /sbin/display $hdr
|
|
} else {
|
|
exec /sbin/display "\$$hd"
|
|
}
|
|
}
|
|
|
|
proc {system tuners} {} {
|
|
if {[system model] eq "HDR"} {
|
|
return 2
|
|
} else {
|
|
return 1
|
|
}
|
|
}
|
|
|
|
proc {system uptime} {} {
|
|
set fd [open /proc/uptime r]
|
|
set uptime [lindex [split [read $fd]] 0]
|
|
$fd close
|
|
return $uptime
|
|
}
|
|
|
|
proc {system filename} {str {extra ""}} {
|
|
# Humax TV replaces these characters.
|
|
# "%*./:<>?\|
|
|
set chars "\"%*\./:<>?\\\\|$extra"
|
|
return [regsub -all -- "\[$chars]" $str "_"]
|
|
}
|
|
|
|
proc {system connectivity} {{site "hpkg.tv"} {port 80} {ret "0"}} {
|
|
set extra [lassign [exec /mod/bin/tcpping $site $port] result]
|
|
if {$ret ne "0"} { upvar $ret err }
|
|
switch $result {
|
|
OK { return 1 }
|
|
default {
|
|
set err [list $result $extra]
|
|
return 0
|
|
}
|
|
}
|
|
}
|
|
|
|
proc {system nuggeted} {} {
|
|
if {![system pkginst nugget]} { return 0 }
|
|
set ret 0
|
|
catch {
|
|
if {[exec /mod/bin/nugget ping] eq "PONG"} {
|
|
set ret 1
|
|
}
|
|
}
|
|
return $ret
|
|
}
|
|
|
|
proc {system strip} {str} {
|
|
if {[string range $str 1 2] eq "i7"} {
|
|
# ISO6937, convert to UTF-8
|
|
return [xconv [string range $str 3 end]]
|
|
}
|
|
if {[string first "\025" $str] == 0} {
|
|
# UTF-8
|
|
return [string range $str 1 end]
|
|
}
|
|
return [xconv $str]
|
|
}
|
|
|
|
proc {system usbdisks} {{full 0}} {
|
|
set disks [lmap i [glob -nocomplain \
|
|
-directory /sys/bus/usb/drivers/usb-storage *:*] {
|
|
file tail $i
|
|
}]
|
|
if {!$full} {
|
|
return [llength $disks]
|
|
}
|
|
if {![llength $disks]} { return {} }
|
|
|
|
# Build list of device to device ID
|
|
set map {}
|
|
foreach block [glob -nocomplain -directory /sys/block sd?] {
|
|
set link [file readlink $block/device]
|
|
foreach disk $disks {
|
|
if {[string first "/$disk/" $link] >= 0} {
|
|
set map([file tail $block]) $disk
|
|
}
|
|
}
|
|
|
|
}
|
|
return $map
|
|
}
|
|
|
|
proc {system usbmounts} {{full 0}} {
|
|
if {!$full} {
|
|
set num 0
|
|
catch {
|
|
set num [
|
|
exec grep -cE {/media/([a-z-]+-)?drive} \
|
|
/proc/mounts]
|
|
}
|
|
return $num
|
|
}
|
|
set ret {}
|
|
if {[catch {
|
|
set lines [exec grep -E {media/([a-z-]+-)?drive} \
|
|
/proc/mounts]
|
|
}]} { return $ret }
|
|
foreach line [split $lines "\n"] {
|
|
lassign $line dev mp
|
|
set rec "DEV $dev MP $mp LABEL {NO NAME} TYPE Unknown"
|
|
|
|
set rec(VENDOR) Unknown
|
|
set rec(MODEL) Unknown
|
|
|
|
if {[regexp {/dev/(sd[a-z])} $dev x rdev]} {
|
|
set rec(RDEV) $rdev
|
|
if {[file readable [
|
|
set f /sys/block/$rdev/device/vendor]]} {
|
|
set rec(VENDOR) [string trim [file read $f]]
|
|
}
|
|
if {[file readable [
|
|
set f /sys/block/$rdev/device/model]]} {
|
|
set rec(MODEL) [string trim [file read $f]]
|
|
}
|
|
}
|
|
|
|
lassign [exec stat -f -c {%S %b %f} $mp] blocks blockc blockf
|
|
set rec(SIZE) $($blockc * $blocks)
|
|
set rec(USED) $(100 - $blockf * 100 / $blockc)
|
|
|
|
# /dev/sda1: LABEL="SAN" UUID="DBC1-1CF8" TYPE="vfat"
|
|
catch {
|
|
foreach field [
|
|
split [exec /mod/sbin/blkid -c /dev/null $dev] "\n"] {
|
|
while {[regexp { *([A-Z]+)="?([^"]+)"?(.*)} \
|
|
$field x k v field]} {
|
|
set rec($k) $v
|
|
}
|
|
}
|
|
}
|
|
# Test for EXFAT
|
|
if {$rec(TYPE) eq "Unknown" && [
|
|
file exists /mod/sbin/exfatlabel]} {
|
|
catch {
|
|
set label [exec /mod/sbin/exfatlabel $dev 2>/dev/null]
|
|
if {$label ne ""} {
|
|
set rec(TYPE) "EXFAT"
|
|
set rec(LABEL) $label
|
|
}
|
|
}
|
|
}
|
|
|
|
lappend ret $rec
|
|
}
|
|
|
|
return $ret
|
|
}
|
|
|
|
proc {system has} {comp} {
|
|
switch $comp {
|
|
wifi_dongle {
|
|
if {[catch {exec /mod/bin/iwgetid}]} { return 0 }
|
|
return 1
|
|
}
|
|
tvdb {
|
|
require settings.class
|
|
return [[settings] _nval_setting tvdb]
|
|
}
|
|
}
|
|
return 0
|
|
}
|
|
|
|
# Note that {system checkop} can be called from processes other than that
|
|
# which started the operation. Hence no visilibty into the ::system::ops
|
|
# dictionary.
|
|
proc {system checkop} {op} {
|
|
if {![regexp -nocase -- {^[.a-z0-9]+$} $op]} { return 0 }
|
|
if {[catch {set fp [open "/tmp/.bgop.$op" "a"]}]} {
|
|
return 0
|
|
}
|
|
set ret 1
|
|
if {[$fp lock]} {
|
|
$fp unlock
|
|
set ret 0
|
|
}
|
|
$fp close
|
|
return $ret
|
|
}
|
|
|
|
set ::system::ops {}
|
|
|
|
proc {system startop} {args op file} {
|
|
if {![regexp -nocase -- {^[a-z0-9]+$} $op]} { return 0 }
|
|
if {"-multiple" in $args} {
|
|
set i 0
|
|
append op "[pid]."
|
|
while {[dict exists $::system::ops "$op$i"]} { incr i }
|
|
append op $i
|
|
} elseif {[dict exists $::system::ops $op]} {
|
|
system endop $op
|
|
}
|
|
if {[catch {
|
|
set fp [open "/tmp/.bgop.$op" "a"]
|
|
if {[$fp lock]} {
|
|
$fp puts "$file\n[pid]"
|
|
$fp flush
|
|
set ::system::ops($op) $fp
|
|
} else {
|
|
$fp close
|
|
error "Could not lock op file."
|
|
}
|
|
}]} { return 0 }
|
|
return $op
|
|
}
|
|
|
|
proc {system endop} {op} {
|
|
if {![regexp -nocase -- {^[.a-z0-9]+$} $op]} { return 0 }
|
|
if {[dict exists $::system::ops $op]} {
|
|
catch {
|
|
set fp $::system::ops($op)
|
|
$fp unlock
|
|
$fp close
|
|
}
|
|
dict unset ::system::ops $op
|
|
}
|
|
if {[file exists "/tmp/.bgop.$op"]} {
|
|
file delete "/tmp/.bgop.$op"
|
|
return 1
|
|
}
|
|
return 0
|
|
}
|
|
|
|
proc {system specialdir} {dir} {
|
|
if {[string match {\[*} [string trimleft [file tail $dir]]]} {
|
|
return 1
|
|
}
|
|
return 0
|
|
}
|
|
|