From eb52e3004a829b73ddea535a881a0161ff19fa55 Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Sat, 19 Jun 2004 18:00:00 +0200 Subject: =?UTF-8?q?Version=201.3.11=20-=20In=20order=20to=20avoid=20proble?= =?UTF-8?q?ms=20on=20NPTL=20systems,=20VDR=20now=20checks=20for=20the=20pr?= =?UTF-8?q?esence=20=20=20of=20NPTL=20at=20program=20start,=20and=20if=20i?= =?UTF-8?q?t=20is,=20exits=20and=20tells=20the=20user=20to=20do=20=20=20'e?= =?UTF-8?q?xport=20LD=5FASSUME=5FKERNEL=3D2.4.1'=20before=20starting=20VDR?= =?UTF-8?q?.=20-=20Revisited=20the=20"Fixed=20missing=20audio=20after=20re?= =?UTF-8?q?playing=20a=20DVD"=20change=20because=20it=20=20=20introduced?= =?UTF-8?q?=20a=20sound=20disturbance=20when=20switching=20between=20chann?= =?UTF-8?q?els=20on=20the=20same=20=20=20transponder=20(thanks=20to=20Marc?= =?UTF-8?q?o=20Schl=C3=BC=C3=9Fler).=20-=20In=20order=20to=20avoid=20probl?= =?UTF-8?q?ems=20on=20UTF-8=20systems,=20VDR=20now=20checks=20for=20the=20?= =?UTF-8?q?presence=20=20=20of=20UTF-8=20at=20program=20start,=20and=20if?= =?UTF-8?q?=20it=20is,=20exits=20and=20tells=20the=20user=20to=20turn=20of?= =?UTF-8?q?f=20=20=20UTF-8=20before=20starting=20VDR=20(thanks=20to=20Ludw?= =?UTF-8?q?ig=20Nussel=20for=20pointing=20out=20a=20problem=20=20=20with?= =?UTF-8?q?=20systems=20that=20are=20set=20to=20use=20UTF-8).=20There=20ar?= =?UTF-8?q?e=20also=20problems=20in=20case=20the=20=20=20video=20partition?= =?UTF-8?q?=20is=20mounted=20with=20"iocharset=3Dutf8"=20(thanks=20to=20J?= =?UTF-8?q?=C3=B6rg=20Knitter=20for=20=20=20reporting=20this=20one).=20=20?= =?UTF-8?q?=20Please=20also=20read=20the=20"IMPORTANT=20NOTES"=20section?= =?UTF-8?q?=20in=20the=20INSTALL=20file!=20-=20Some=20changes=20to=20the?= =?UTF-8?q?=20SPU=20decoder=20interface=20(thanks=20to=20Sven=20Goethel).?= =?UTF-8?q?=20-=20Some=20improvements=20in=20cOsd=20creation=20(thanks=20t?= =?UTF-8?q?o=20some=20suggestions=20by=20Jouni=20Karvo).=20-=20Fixed=20cal?= =?UTF-8?q?culating=20the=20OSD=20width=20and=20height=20(thanks=20to=20Ol?= =?UTF-8?q?af=20Henkel=20for=20reporting=20=20=20a=20problem=20with=20long?= =?UTF-8?q?=20event=20texts=20in=20the=20"Classic=20VDR"=20skin).=20-=20Fi?= =?UTF-8?q?xed=20switching=20channels=20while=20an=20encrypted=20channel?= =?UTF-8?q?=20is=20being=20recorded,=20because=20the=20=20=20channel=20was?= =?UTF-8?q?=20switched=20if=20the=20new=20channel=20was=20on=20the=20same?= =?UTF-8?q?=20transponder=20and=20was=20=20=20a=20radio=20channel=20or=20a?= =?UTF-8?q?n=20unencrypted=20channel=20(thanks=20to=20Martin=20Dauskardt?= =?UTF-8?q?=20for=20reporting=20=20=20this=20one).=20-=20No=20longer=20usi?= =?UTF-8?q?ng=20the=20external=20'find'=20command=20to=20scan=20the=20vide?= =?UTF-8?q?o=20directory=20for=20=20=20recordings=20(based=20on=20a=20sugg?= =?UTF-8?q?estion=20by=20Mirko=20D=C3=B6lle).=20-=20The=20list=20of=20reco?= =?UTF-8?q?rdings=20is=20now=20kept=20statically=20in=20memory=20to=20avoi?= =?UTF-8?q?d=20long=20delays=20=20=20when=20opening=20the=20"Recordings"?= =?UTF-8?q?=20menu.=20As=20a=20side=20effect,=20external=20modifications?= =?UTF-8?q?=20to=20=20=20the=20video=20directory=20are=20no=20longer=20imm?= =?UTF-8?q?ediately=20reflected=20in=20the=20"Recordings"=20menu.=20=20=20?= =?UTF-8?q?If=20a=20plugin=20manipulates=20the=20video=20directory=20in=20?= =?UTF-8?q?any=20way,=20it=20can=20call=20the=20function=20=20=20Recording?= =?UTF-8?q?s.TriggerUpdate()=20to=20trigger=20an=20update=20of=20the=20lis?= =?UTF-8?q?t=20of=20recordings.=20=20=20If=20some=20external=20tool=20mani?= =?UTF-8?q?pulates=20the=20video=20directory,=20it=20can=20touch=20the=20f?= =?UTF-8?q?ile=20=20=20'.update'=20in=20the=20video=20directory=20to=20tri?= =?UTF-8?q?gger=20an=20update=20of=20the=20list=20of=20recordings.=20-=20F?= =?UTF-8?q?ixed=20a=20memory=20leak=20in=20theme=20description=20handling?= =?UTF-8?q?=20(thanks=20to=20Sascha=20Volkenandt).=20-=20Added=20cDevice::?= =?UTF-8?q?Flush()=20to=20make=20sure=20that=20all=20data=20in=20the=20vid?= =?UTF-8?q?eo=20card's=20buffers=20=20=20has=20been=20processed=20(thanks?= =?UTF-8?q?=20to=20Reinhard=20Nissl).=20Currently=20this=20is=20not=20yet?= =?UTF-8?q?=20actually=20=20=20implemented=20for=20FF=20DVB=20cards.=20-?= =?UTF-8?q?=20Fixed=20handling=20the=20color=20button=20texts=20in=20cMenu?= =?UTF-8?q?EditStrItem=20(thanks=20to=20Maynard=20=20=20Cedric=20for=20rep?= =?UTF-8?q?orting=20this=20one).=20-=20Fixed=20the=20description=20of=20cR?= =?UTF-8?q?ingBufferLinear=20(thanks=20to=20Ludwig=20Nussel=20for=20pointi?= =?UTF-8?q?ng=20=20=20out=20this=20one).=20-=20Fixed=20cRingBufferLinear::?= =?UTF-8?q?Get()=20in=20case=20the=20buffer=20wraps=20around=20(thanks=20t?= =?UTF-8?q?o=20Ludwig=20=20=20Nussel=20for=20reporting=20this=20one).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- recording.c | 132 ++++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 97 insertions(+), 35 deletions(-) (limited to 'recording.c') diff --git a/recording.c b/recording.c index 05efc44..cbc916a 100644 --- a/recording.c +++ b/recording.c @@ -4,10 +4,11 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: recording.c 1.87 2004/05/07 14:24:18 kls Exp $ + * $Id: recording.c 1.88 2004/06/13 20:25:19 kls Exp $ */ #include "recording.h" +#include #include #include #include @@ -25,7 +26,7 @@ #define RECEXT ".rec" #define DELEXT ".del" /* This was the original code, which works fine in a Linux only environment. - Unfortunately, because of windows and its brain dead file system, we have + Unfortunately, because of Windows and its brain dead file system, we have to use a more complicated approach, in order to allow users who have enabled the VFAT compile time option to see their recordings even if they forget to enable VFAT when compiling a new version of VDR... Gee, do I hate Windows. @@ -47,8 +48,6 @@ #define SUMMARYFILESUFFIX "/summary.vdr" #define MARKSFILESUFFIX "/marks.vdr" -#define FINDCMD "cd '%s' && find '%s' -follow -type d -name '%s' 2> /dev/null" - #define MINDISKSPACE 1024 // MB #define DELETEDLIFETIME 1 // hours after which a deleted recording will be actually removed @@ -70,14 +69,14 @@ void RemoveDeletedRecordings(void) if (!LockFile.Lock()) return; // Remove the oldest file that has been "deleted": - cRecordings Recordings; - if (Recordings.Load(true)) { - cRecording *r = Recordings.First(); + cRecordings DeletedRecordings(true); + if (DeletedRecordings.Load()) { + cRecording *r = DeletedRecordings.First(); cRecording *r0 = r; while (r) { if (r->start < r0->start) r0 = r; - r = Recordings.Next(r); + r = DeletedRecordings.Next(r); } if (r0 && time(NULL) - r0->start > DELETEDLIFETIME * 3600) { r0->Remove(); @@ -105,14 +104,14 @@ void AssertFreeDiskSpace(int Priority) return; // Remove the oldest file that has been "deleted": isyslog("low disk space while recording, trying to remove a deleted recording..."); - cRecordings Recordings; - if (Recordings.Load(true)) { - cRecording *r = Recordings.First(); + cRecordings DeletedRecordings(true); + if (DeletedRecordings.Load()) { + cRecording *r = DeletedRecordings.First(); cRecording *r0 = r; while (r) { if (r->start < r0->start) r0 = r; - r = Recordings.Next(r); + r = DeletedRecordings.Next(r); } if (r0 && r0->Remove()) { LastFreeDiskCheck += REMOVELATENCY / Factor; @@ -121,7 +120,7 @@ void AssertFreeDiskSpace(int Priority) } // No "deleted" files to remove, so let's see if we can delete a recording: isyslog("...no deleted recording found, trying to delete an old recording..."); - if (Recordings.Load(false)) { + if (Recordings.Load()) { cRecording *r = Recordings.First(); cRecording *r0 = NULL; while (r) { @@ -138,8 +137,10 @@ void AssertFreeDiskSpace(int Priority) } r = Recordings.Next(r); } - if (r0 && r0->Delete()) + if (r0 && r0->Delete()) { + Recordings.Del(r0); return; + } } // Unable to free disk space, but there's nothing we can do about that... isyslog("...no old recording found, giving up"); @@ -617,30 +618,75 @@ bool cRecording::Remove(void) // --- cRecordings ----------------------------------------------------------- -bool cRecordings::Load(bool Deleted) +cRecordings Recordings; + +cRecordings::cRecordings(bool Deleted) { - Clear(); - bool result = false; - char *cmd = NULL; - asprintf(&cmd, FINDCMD, VideoDirectory, VideoDirectory, Deleted ? "*" DELEXT : "*" RECEXT); - FILE *p = popen(cmd, "r"); - if (p) { - char *s; - while ((s = readline(p)) != NULL) { - cRecording *r = new cRecording(s); - if (r->Name()) - Add(r); - else - delete r; + deleted = Deleted; + lastUpdate = 0; +} + +bool cRecordings::ScanVideoDir(const char *DirName) +{ + DIR *d = opendir(DirName); + if (d) { + struct dirent *e; + while ((e = readdir(d)) != NULL) { + if (strcmp(e->d_name, ".") && strcmp(e->d_name, "..")) { + char *buffer; + asprintf(&buffer, "%s/%s", DirName, e->d_name); + struct stat st; + if (stat(buffer, &st) == 0) { + if (S_ISLNK(st.st_mode)) { + free(buffer); + buffer = ReadLink(buffer); + if (!buffer) + return false; + if (stat(buffer, &st) != 0) { + LOG_ERROR_STR(DirName); + return false; + } + } + if (S_ISDIR(st.st_mode)) { + if (endswith(buffer, deleted ? DELEXT : RECEXT)) { + cRecording *r = new cRecording(buffer); + if (r->Name()) + Add(r); + else + delete r; + } + else if (!ScanVideoDir(buffer)) + return false; + } + } + else { + LOG_ERROR_STR(DirName); + return false; + } + free(buffer); + } } - pclose(p); - Sort(); - result = Count() > 0; + closedir(d); } - else - Skins.Message(mtError, "Error while opening pipe!"); - free(cmd); - return result; + else { + LOG_ERROR_STR(DirName); + return false; + } + return true; +} + +bool cRecordings::NeedsUpdate(void) +{ + return lastUpdate <= LastModifiedTime(AddDirectory(VideoDirectory, ".update")); +} + +bool cRecordings::Load(void) +{ + lastUpdate = time(NULL); // doing this first to make sure we don't miss anything + Clear(); + ScanVideoDir(VideoDirectory); + Sort(); + return Count() > 0; } cRecording *cRecordings::GetByName(const char *FileName) @@ -652,6 +698,22 @@ cRecording *cRecordings::GetByName(const char *FileName) return NULL; } +void cRecordings::AddByName(const char *FileName) +{ + cRecording *recording = GetByName(FileName); + if (!recording) { + recording = new cRecording(FileName); + Add(recording); + } +} + +void cRecordings::DelByName(const char *FileName) +{ + cRecording *recording = GetByName(FileName); + if (recording) + Del(recording); +} + // --- cMark ----------------------------------------------------------------- char *cMark::buffer = NULL; -- cgit v1.2.3