webif/webif/lib/auto/plugin/decrypt/queue.hook

207 lines
5.5 KiB
Plaintext

proc ::decrypt::dequeue {q ts} {
namespace import ::auto::log
set tmp $::auto::tmp
set file [$ts get file]
set rfile [file rootname $file]
set bfile [file tail $file]
set mode "dlna"
if {[system model] eq "HD"} { set mode "direct" }
if {"-direct" in [$q get args]} { set mode "direct" }
#if {$mode eq "dlna" && [$q get retries] > 5} { set mode "direct" }
if {![$ts flag "ODEncrypted"]} {
return {"OK" "Already decrypted"}
}
if {![$ts size]} {
return {"FAILED" "Zero-byte recording, cannot process"}
}
if {$mode eq "dlna" && ![system dlnastatus]} {
if {[system instandby]} {
# Prevent polling every minute
return [list "DEFER" "Cannot decrypt in standby" +120]
}
return {"DEFER" "DLNA Server not running"}
}
if {[::auto::inuse $ts]} {
if {[clock seconds] < [$ts get end]} {
if {[$ts tsr]} {
return [list "DEFER" \
"Time-shifted recording in-progress" +120]
}
# Recording in progress, defer until near expected
# end.
set left $([$ts get end] - [clock seconds])
if {$left > 360} {
return [list "DEFER" "Recording in progress" \
"+$($left - 300)"]
} else {
return [list "DEFER" "Recording in progress"]
}
}
return [list "DEFER" "Recording in use"]
}
# Check that the file is not already decrypted by analysing it.
if {[catch {set anencd [exec /mod/bin/stripts -qE $rfile]} msg]} {
return [list "DEFER" "plugin failure - $msg"]
}
if {$anencd != "1"} {
exec /mod/webif/lib/bin/fixencflags $file
return {"OK"
"Already decrypted but the HMT flag was wrong (fixed)"}
}
if {$mode eq "dlna"} {
lassign [$ts dlnaloc "127.0.0.1"] url
if {[$ts flag "Encrypted"]} {
#return {"DEFER" "Protected (Enc flag)"}
# Unset the flag but use the DLNA helper to decrypt
# this file since the DLNA database will be wrong.
log " $file - ENC flag set, using helper."
$ts unenc
set url ""
}
if {$url ne ""} {
log " $file - has been indexed."
set helper 0
} else {
log " $file - Not yet indexed, trying helper."
if {[catch {
lassign [system dlnahelper [\
file normalize $file]] url
} msg]} {
log " $file - $msg"
return [list "DEFER" $msg]
}
if {$url eq ""} {
return {"DEFER" "DLNA helper failed"}
}
set helper 1
}
}
set size [$ts size]
::auto::dsc $size
system startop decrypt $file
::auto::startclock
log " DECRYPT: $rfile" 0
if {$mode eq "dlna"} {
if {[$ts getkey $mode] eq ""} {
::auto::log "system key doesn't match, trying direct"
set mode direct
}
}
if {$mode eq "dlna"} {
log " DLNA: $url" 0
if {[catch {exec wget -O "$tmp/$bfile" $url} msg opts]} {
::auto::log "Wget error - $msg - $opts"
}
# Release the helper lock once finished.
if {$helper} { system dlnahelper -release }
} else {
log " Direct decryption" 0
set key [$ts getkey $mode]
if {$key eq ""} {
return {"FAILED" "No matching key for decryption"}
}
::auto::log "Using key ($key)" 2
if {[catch {exec /mod/bin/stripts -@ $key $rfile "$tmp/[\
file rootname $bfile]" } msg opts]} {
::auto::log "Decrypt error - $msg - $opts"
system endop decrypt
return {"FAILED" "Decryption failed"}
}
}
if {![file exists "$tmp/$bfile"]} {
log " $file - Download failed." 0
system endop decrypt
return {"DEFER" "File download failed"}
}
if {[file size $file] != [file size "$tmp/$bfile"]} {
log " $file - File size mismatch." 0
file tdelete "$tmp/$bfile"
system endop decrypt
return {"DEFER" "File size mismatch"}
}
# Check if the file is in use. It is possible that the file is
# now being played even though it was free when decryption started.
if {[::auto::inuse $ts]} {
log " $file - In use."
file tdelete "$tmp/$bfile"
system endop decrypt
return {"DEFER" "Recording in use"}
}
# Copy the HMT file over for stripts
set thmt "$tmp/[file rootname $bfile].hmt"
if {![file exists $thmt]} { file copy "$rfile.hmt" $thmt }
# Check that the file is no longer encrypted by analysing it.
set anencd [exec /mod/bin/stripts -qE "$tmp/[file rootname $bfile]"]
file delete $thmt
if {$anencd != "0"} {
log " $file - File did not decrypt properly." 0
file tdelete "$tmp/$bfile"
system endop decrypt
if {[$q get retries] > 3} {
system notify "$file - auto-decrypt failed."
return {"FAILED" "Recording did not decrypt properly"}
}
return {"DEFER" "Recording did not decrypt properly"}
}
# Move the encrypted file out of the way.
file rename $file "$rfile.encrypted"
# Move the decrypted copy into place.
file rename "$tmp/$bfile" $file
# Set the file time to match the old file
file touch $file "$rfile.encrypted"
# Patch the HMT - quickest way to get back to a playable file.
exec /mod/bin/hmt -encrypted "$rfile.hmt"
log " Removing/binning old copy." 0
# Move the old recording to the bin if undelete is installed.
if {![$::auto::settings autoskipbin] && $::auto::dustbin ne ""} {
log " finding bin for $file" 0
set bin [_del_bindir $file "webif_autodecrypt"]
log " bin = ($bin)" 0
set tail [file tail $rfile]
file rename "$rfile.encrypted" "$bin/$tail.ts"
foreach ext {nts hmt thm} {
if {[file exists "$rfile.$ext"]} {
file copy $rfile.$ext "$bin/$tail.$ext"
if {$ext eq "hmt"} {
# Patch the binned HMT back
exec /mod/bin/hmt +encrypted \
"$bin/$tail.hmt"
}
}
}
} else {
file tdelete "$rfile.encrypted"
}
set summary [::auto::endclock $size]
$ts unflag "ODEncrypted"
system endop decrypt
return [list "OK" $summary]
}
::auto::register decrypt 900