summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAndreas Brachold <vdr07@deltab.de>2009-04-19 08:29:25 +0000
committerAndreas Brachold <vdr07@deltab.de>2009-04-19 08:29:25 +0000
commit830433b7a218da8016f6ddd6e240955043c35027 (patch)
tree041edc59c9997bcce5e37e299d10e3d51e3689f4 /lib
parent26182d1a1f2d32bc8ed6953fdb56d1623055e0a7 (diff)
downloadxxv-830433b7a218da8016f6ddd6e240955043c35027.tar.gz
xxv-830433b7a218da8016f6ddd6e240955043c35027.tar.bz2
* RECORDS: Fix file monitor don't work if path contain symbolic links (resolv now real file name)
Diffstat (limited to 'lib')
-rw-r--r--lib/Tools.pm30
-rw-r--r--lib/XXV/MODULES/RECORDS.pm137
2 files changed, 103 insertions, 64 deletions
diff --git a/lib/Tools.pm b/lib/Tools.pm
index f745387..30b3325 100644
--- a/lib/Tools.pm
+++ b/lib/Tools.pm
@@ -33,7 +33,7 @@ use constant FRAMESPERSECOND => 25;
&getFromSocket &fields &load_file &save_file &tableUpdated &buildsearch
&deleteDir &getip &convert &int &entities &reentities &bench &fmttime
&getDataByTable &getDataById &getDataBySearch &getDataByFields &touch &url
- &con_err &con_msg &text2frame &frame2hms &gettext &setcharset);
+ &con_err &con_msg &text2frame &frame2hms &gettext &setcharset &resolv_symlink);
# ------------------
@@ -767,5 +767,33 @@ sub gettext($) {
return encode($CHARSET,$text);
}
}
+################################################################################
+# dereference symbolic link to real filename
+sub resolv_symlink($) {
+ my $file = shift;
+
+ my @f = split (m|/|, $file); #split file by path /
+ my $deep = 0;
+ for(my $n = 0; $n <= $#f; ++$n) {
+ my $k = join ("/", @f[0 .. $n]);
+ my $orig = $k;
+ while(my $l = readlink ($k)) {
+ $k = $l;
+ if ($deep++ == 64) {
+ error sprintf ("File %s has too many levels of symbolic links" , $file);
+ return undef;
+ }
+ }
+ next if($k eq $orig);
+ if(substr ($k, 0, 1) eq "/") {
+ splice(@f, 0, $n + 1, split (m|/|, $k));
+ $n = -1;
+ } else {
+ splice(@f, $n, 1, split(m|/|, $k));
+ $n--;
+ }
+ }
+ return join("/", @f);
+}
1;
diff --git a/lib/XXV/MODULES/RECORDS.pm b/lib/XXV/MODULES/RECORDS.pm
index 8186a3d..5dcfa42 100644
--- a/lib/XXV/MODULES/RECORDS.pm
+++ b/lib/XXV/MODULES/RECORDS.pm
@@ -223,8 +223,8 @@ sub module {
my $event = shift;
my $record = getDataById($args->{id}, 'RECORDS', 'id');
my $epg = main::getModule('EPG')->getId($record->{eventid}, 'title, subtitle, description');
- my $t = [$epg->{title}];
- push(@$t,$epg->{subtitle}) if($epg->{subtitle});
+ my $t = [$epg->{title}];
+ push(@$t,$epg->{subtitle}) if($epg->{subtitle});
my $topic = sprintf(gettext("Recording deleted: %s"),join('~',@$t));
@@ -248,9 +248,9 @@ sub module {
# ------------------
sub new {
# ------------------
- my($class, %attr) = @_;
- my $self = {};
- bless($self, $class);
+ my($class, %attr) = @_;
+ my $self = {};
+ bless($self, $class);
$self->{charset} = delete $attr{'-charset'};
if($self->{charset} eq 'UTF-8'){
@@ -260,7 +260,7 @@ sub new {
# paths
$self->{paths} = delete $attr{'-paths'};
- # who am I
+ # who am I
$self->{MOD} = $self->module;
# all configvalues to $self without parents (important for ConfigModule)
@@ -387,7 +387,7 @@ sub _watch_recorder {
}
}
-sub _watch_addrecorder {
+sub _watch_filename {
my $self = shift || return error('No object defined!');
my $vid = shift;
@@ -399,6 +399,18 @@ sub _watch_addrecorder {
}
my $updatefile = sprintf("%s/.update",$videodirectory);
if( -r $updatefile) {
+ return resolv_symlink($updatefile);
+ }
+ error(sprintf("Missing state file %s!",$updatefile));
+ return undef;
+}
+
+sub _watch_addrecorder {
+ my $self = shift || return error('No object defined!');
+ my $vid = shift;
+
+ my $updatefile = $self->_watch_filename($vid);
+ if($updatefile) {
if(exists $self->{inotify}
&& exists $self->{inotify}->{$updatefile}) {
@@ -442,15 +454,9 @@ sub _watch_removerecorder {
return;
}
- my $videodirectory = $self->{svdrp}->videodirectory($vid);
- unless($videodirectory && -d $videodirectory) {
- my $hostname = $self->{svdrp}->hostname($vid);
- error(sprintf("Missing video directory on '%s'!",$hostname));
- return;
- }
-
- my $updatefile = sprintf("%s/.update",$videodirectory);
- if(exists $self->{inotify}->{$updatefile}) {
+ my $updatefile = $self->_watch_filename($vid);
+ if($updatefile
+ && exists $self->{inotify}->{$updatefile}) {
unless($force) {
if($self->{inotify}->{$updatefile}->{count} > 1) {
$self->{inotify}->{$updatefile}->{count} -= 1;
@@ -604,8 +610,8 @@ sub scandirectory {
unless(exists $files->{$hash}) {
my $rec;
$rec->{path} = $path;
- # Splitt 2005-01-16.04:35.88.99
- my ($year, $month, $day, $hour, $minute, $priority, $lifetime)
+ # Splitt 2005-01-16.04:35.88.99
+ my ($year, $month, $day, $hour, $minute, $priority, $lifetime)
= (basename($path)) =~ /^(\d+)\-(\d+)\-(\d+)\.(\d+)[\:|\.](\d+)\.(\d+)\.(\d+)\./s;
$rec->{year} = $year;
$rec->{month} = $month;
@@ -1279,21 +1285,19 @@ sub _calcmarks {
my $frames = 0;
for (my $i = 0; $i < (scalar(@$marks)); $i += 2) {
- my ($h,$m,$s,$f) = split /[:.]/,$marks->[$i];
- my $startframe = ($h * 3600 + $m * 60 + $s)* ($self->{framerate}) + $f;
+ my ($h,$m,$s,$f) = split /[:.]/,$marks->[$i];
+ my $startframe = ($h * 3600 + $m * 60 + $s)* ($self->{framerate}) + $f;
if ($marks->[$i+1]) {
- my ($h,$m,$s,$f) = split /[:.]/,$marks->[$i + 1];
- my $endframe = ($h * 3600 + $m * 60 + $s)* ($self->{framerate}) + $f;
+ my ($h,$m,$s,$f) = split /[:.]/,$marks->[$i + 1];
+ my $endframe = ($h * 3600 + $m * 60 + $s)* ($self->{framerate}) + $f;
$frames += $endframe - $startframe;
} else {
$frames += ($duration * ($self->{framerate})) - $startframe;
last;
}
}
-
return $frames / $self->{framerate};
-
}
#-------------------------------------------------------------------------------
@@ -1523,11 +1527,11 @@ sub videoPreview {
my $startseconds = ($self->{timers}->{prevminutes} * 60) * 2;
my $endseconds = ($self->{timers}->{afterminutes} * 60) * 2;
my $stepseconds = ($info->{duration} - ($startseconds + $endseconds)) / $count;
- # reduced interval on short movies
- if($stepseconds <= 0 or ($startseconds + ($count * $stepseconds)) > $info->{duration}) {
- $stepseconds = $info->{duration} / ( $count + 2 ) ;
- $startseconds = $stepseconds;
- }
+ # reduced interval on short movies
+ if($stepseconds <= 0 or ($startseconds + ($count * $stepseconds)) > $info->{duration}) {
+ $stepseconds = $info->{duration} / ( $count + 2 ) ;
+ $startseconds = $stepseconds;
+ }
if($info->{duration} <= $count or $stepseconds <= 1) { # dont' create to early ?
lg sprintf("Recording just started, create images for '%s' later.", $info->{title});
@@ -1606,11 +1610,11 @@ sub videoPreview {
sub _mark2frames{
- my $self = shift;
- my $mark = shift;
- my($h, $m, $s, $f) = split /[:.]/, $mark;
- my $frame = (3600 * $h + 60 * $m + $s) * $self->{framerate} + $f ;
- return $frame;
+ my $self = shift;
+ my $mark = shift;
+ my($h, $m, $s, $f) = split /[:.]/, $mark;
+ my $frame = (3600 * $h + 60 * $m + $s) * $self->{framerate} + $f ;
+ return $frame;
};
# ------------------
@@ -2063,7 +2067,7 @@ FROM
$tables
WHERE
e.eventid = r.eventid
- AND ( $search )
+ AND ( $search )
ORDER BY
|;
@@ -2301,7 +2305,7 @@ FROM
OLDEPG as e
WHERE
e.eventid = r.eventid
- AND ( r.hash = ? )
+ AND ( r.hash = ? )
|;
my $sth = $self->{dbh}->prepare($sql);
if(!$sth->execute($id)
@@ -2316,8 +2320,8 @@ WHERE
my $marksfile = sprintf('%s/%s', $rec->{Path}, 'marks.vdr');
my $marks = (-r $marksfile ? load_file($marksfile) : '');
- $rec->{title} =~s#~+#~#g;
- $rec->{title} =~s#^~##g;
+ $rec->{title} =~s#~+#~#g;
+ $rec->{title} =~s#^~##g;
$rec->{title} =~s#~$##g;
my $modC = main::getModule('CHANNELS');
@@ -2341,7 +2345,7 @@ WHERE
}
},
req => gettext("This is required!"),
- },
+ },
'priority' => {
typ => 'integer',
msg => sprintf(gettext('Priority (%d ... %d)'),0,99),
@@ -2356,7 +2360,7 @@ WHERE
},
req => gettext("This is required!"),
},
- 'channel' => {
+ 'channel' => {
typ => 'list',
def => $status->{channel},
choices => sub {
@@ -2380,21 +2384,21 @@ WHERE
msg => gettext("Description"),
def => $status->{description} || '',
},
- 'aux' => {
+ 'aux' => {
typ => 'hidden',
def => $status->{aux},
},
- 'keywords' => {
+ 'keywords' => {
typ => $self->{keywords}->{active} eq 'y' ? 'string' : 'hidden',
msg => gettext('Keywords'),
def => $status->{keywords},
},
- 'video' => {
+ 'video' => {
typ => 'textfield',
msg => gettext('Video'),
def => $status->{video},
},
- 'audio' => {
+ 'audio' => {
typ => 'textfield',
msg => gettext('Audio'),
def => $status->{audio},
@@ -2420,8 +2424,8 @@ WHERE
return;
}
- $data->{title} =~s#~+#~#g;
- $data->{title} =~s#^~##g;
+ $data->{title} =~s#~+#~#g;
+ $data->{title} =~s#^~##g;
$data->{title} =~s#~$##g;
# Keep PDC Time
@@ -2522,7 +2526,11 @@ WHERE
}
if($dropEPGEntry || $ChangeRecordingData) {
$self->{lastupdate} = 0;
- touch($videodirectory."/.update");
+ my $updatefilename = $self->_watch_filename($rec->{vid});
+ if($updatefilename) {
+ touch($updatefilename)
+ or con_err($console,sprintf(gettext("Sorry! Couldn't touch '%s'! %s"), $updatefilename, $!));
+ }
}
if($dropEPGEntry || $ChangeRecordingData) {
my $waiter;
@@ -2869,7 +2877,7 @@ sub suggest {
OLDEPG as e
WHERE
e.eventid = r.eventid
- AND ( e.title LIKE ? )
+ AND ( e.title LIKE ? )
GROUP BY
title
UNION
@@ -2880,7 +2888,7 @@ UNION
OLDEPG as e
WHERE
e.eventid = r.eventid
- AND ( e.subtitle LIKE ? )
+ AND ( e.subtitle LIKE ? )
GROUP BY
title
ORDER BY
@@ -2906,7 +2914,7 @@ sub recover {
my $data = shift || 0;
my $files;
- my $directories;
+ my $vids;
my $hostlist = $self->{svdrp}->list_unique_recording_hosts();
foreach my $vid (@$hostlist) {
@@ -2919,8 +2927,8 @@ sub recover {
}
my $f = $self->scandirectory($videodirectory, 'del');
if($f) {
- map { $files->{$_} = $f->{$_}; } keys %{$f};
- push(@$directories, $videodirectory);
+ map { $files->{$_} = $f->{$_}; } keys %{$f};
+ $vids->{$vid} = $videodirectory;
}
}
@@ -2979,8 +2987,12 @@ sub recover {
my $waiter;
$self->{lastupdate} = 0;
- foreach my $d (@$directories) {
- touch($d."/.update");
+ foreach my $v (keys %{$vids}) {
+ my $updatefilename = $self->_watch_filename($v);
+ if($updatefilename) {
+ touch($updatefilename)
+ or con_err($console,sprintf(gettext("Sorry! Couldn't touch '%s'! %s"), $updatefilename, $!));
+ }
}
if(ref $console && $console->typ eq 'HTML' && !($self->{inotify})) {
@@ -3014,43 +3026,42 @@ sub frametofile {
use constant FRAMESTRUCTSIZE => 8;
my $f = sprintf("%s/index.vdr", $path);
- unless(open FH,$f) {
+ unless(open FH,$f) {
error(sprintf("Can't open file '%s': %s",$f,$!));
return (undef,undef);
}
- binmode FH;
+ binmode FH;
my $offset = FRAMESTRUCTSIZE * $frame;
if($offset != sysseek(FH,$offset,0)) { #SEEK_SET
error(sprintf("Can't seek file '%s': %s",$f,$!));
- close FH;
+ close FH;
return (undef,undef);
}
do {
- my $buffer;
- my $bytesread = sysread (FH, $buffer, FRAMESTRUCTSIZE);
+ my $buffer;
+ my $bytesread = sysread (FH, $buffer, FRAMESTRUCTSIZE);
if($bytesread != FRAMESTRUCTSIZE) {
error(sprintf("Can't read file '%s': %s",$f,$!));
return (undef,undef);
}
my ($c, $t, $n, $r) = unpack ("I C C S", $buffer);
if($t == 1) { # I-Frame
- close FH;
+ close FH;
return ($n,$c); # Filenumber, Offset from file begin
}
$offset -= FRAMESTRUCTSIZE;
if($offset != sysseek(FH,-(FRAMESTRUCTSIZE*2), 1)) { #SEEK_CUR
error(sprintf("Can't seek file '%s': %s",$f,$!));
- close FH;
+ close FH;
return (undef,undef);
}
$frame -= 1;
} while($frame >= 0 && $offset >= 0);
- close FH;
-
+ close FH;
return (undef,undef);
}