source /mod/webif/lib/setup 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 } # 822272+6 - MAC address # 833536 - Serial number proc {system serialno} {} {{serial ""}} { if {$serial ne ""} { return $serial } set fd [open /dev/mtd3 r] $fd seek 833536 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 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" } "Nov 18 19:16:42 GMT 2015" { format "HDR_CFW_3.10" } # 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} {} { set part [system diskpart] foreach line [split [\ exec /mod/bin/busybox/df $part 2>>/dev/null] "\n\r"] { if {[string match "/*" $line]} { lassign [split $line] dev break } } return $dev } proc {system disk} {} { return [string range [system diskdev] 0 end-1] } proc {system disktemp} {} { if {[catch { set smart [exec /mod/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 lassign [exec du -ks $tsrdir] tsrused 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} {} { 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 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 strip} {str} { if {[string range $str 1 2] eq "i7"} { set str [string range $str 3 end] } if {[string first "\025" $str] == 0} { set str [string range $str 1 end] } return $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/(usb-|gpt-)?drive} \ /proc/mounts] } return $num } set ret {} if {[catch { set lines [exec grep -E {media/(usb-|gpt-)?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 }