diff options
author | Klaus Schmidinger <kls (at) cadsoft (dot) de> | 2001-10-21 18:00:00 +0200 |
---|---|---|
committer | Klaus Schmidinger <kls (at) cadsoft (dot) de> | 2001-10-21 18:00:00 +0200 |
commit | 8465398c6d2a57bc30a07fb61353a7c8ba6db574 (patch) | |
tree | f2e14e51ab0a43ebd3c148376c5be73f4bd1434d | |
parent | 66bab90b60048a46e401ea506d3aa65c43779700 (diff) | |
download | vdr-patch-lnbsharing-8465398c6d2a57bc30a07fb61353a7c8ba6db574.tar.gz vdr-patch-lnbsharing-8465398c6d2a57bc30a07fb61353a7c8ba6db574.tar.bz2 |
Version 0.97vdr-0.97
- Implemented a lock file to prevent more than one instance of VDR from removing
files from the video directory at the same time.
- The new setup parameter SplitEditedFiles can be used to control whether or
not the result of an editing process shall be written into separate files.
- Fixed handling repeat function when using LIRC (thanks to Matthias Weingart).
- The shutdown program (defined with the '-s' option) now also gets the channel
number and recording title of the timer (see INSTALL).
- New channel data for 'Premiere One', 'Premiere X-Action', 'Fox Kids Türkce'
and 'N24' (thanks to Andreas Share, Ulrich Röder, Uwe Scheffler and Simon
Bauschulte). Note that if you are using the default 'channels.conf' or
'channels.conf.cable' files you may need to check any exiting timers to see
whether they still use the correct channel number.
- Fixed the "EPG bugfix" (sometimes had duplicate information in Subtitle and
Extended Description).
- Fixed checking for valid video device when setting the video mode.
- The external command 'sort' is no longer required. VDR now sorts the list of
recordings itself, making sure that recordings that stem from repeating timers
are sorted chronologically. Sorting is done according to the setting of the
current locale, so you may want to make sure LC_COLLATE is set to the desired
value (see INSTALL).
- Fixed handling 'newline' characters in EPG texts (thanks to Rolf Hakenes for
an improved version of his 'libdtv').
Newline characters are always mapped to a single "blank" in VDR, because they
would otherwise disturb the Title and Subtitle layout in the channel display
(where these are assumed to be single line texts) and would have to be
specially handled in the 'epg.data' file and the LSTE command in SVDRP.
- Mapping ` ("backtick") characters in EPG texts to ' (single quote).
- Fixed timers starting and ending at unexpected times. 'localtime()' was not
thread safe, now using localtime_r().
- Removed the "system time seen..." message.
- Fixed a bug in the replay mode display when pressing the Green or Yellow
button while in trick mode (thanks to Stefan Huelswitt)
- Closing all open file descriptors when calling external programs.
- The menu timeout now also works when pressing the "Back" button during replay
to enter the "Recordings" menu.
- Updated 'channels.conf' for the "Bundesliga" channels of Premiere World
(thanks to Helmut Schächner).
- Fixed reading timers.conf and channels.conf that contain blanks after numeric
values.
- Fixed handling trick modes near the beginning and end of a recording.
- Pressing the "Back" button while replaying a DVD now leads to the DVD menu.
-rw-r--r-- | CONTRIBUTORS | 10 | ||||
-rw-r--r-- | HISTORY | 44 | ||||
-rw-r--r-- | INSTALL | 26 | ||||
-rw-r--r-- | MANUAL | 11 | ||||
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | channels.conf | 24 | ||||
-rw-r--r-- | channels.conf.cable | 151 | ||||
-rw-r--r-- | config.c | 37 | ||||
-rw-r--r-- | config.h | 6 | ||||
-rw-r--r-- | dvbapi.c | 130 | ||||
-rw-r--r-- | eit.c | 35 | ||||
-rw-r--r-- | i18n.c | 11 | ||||
-rw-r--r-- | libdtv/Makefile | 6 | ||||
-rw-r--r-- | libdtv/liblx/Makefile | 6 | ||||
-rw-r--r-- | libdtv/liblx/liblx.h | 6 | ||||
-rw-r--r-- | libdtv/liblx/xListFuncs.c | 2 | ||||
-rw-r--r-- | libdtv/liblx/xMemMgt.c | 2 | ||||
-rw-r--r-- | libdtv/libsi/Makefile | 8 | ||||
-rw-r--r-- | libdtv/libsi/include/libsi.h | 178 | ||||
-rw-r--r-- | libdtv/libsi/include/si_tables.h | 66 | ||||
-rw-r--r-- | libdtv/libsi/si_debug_services.c | 62 | ||||
-rw-r--r-- | libdtv/libsi/si_debug_services.h | 2 | ||||
-rw-r--r-- | libdtv/libsi/si_parser.c | 72 | ||||
-rw-r--r-- | libdtv/libvdr/Makefile | 6 | ||||
-rw-r--r-- | libdtv/libvdr/libvdr.c | 4 | ||||
-rw-r--r-- | libdtv/libvdr/libvdr.h | 6 | ||||
-rw-r--r-- | menu.c | 26 | ||||
-rw-r--r-- | menu.h | 7 | ||||
-rw-r--r-- | recording.c | 66 | ||||
-rw-r--r-- | recording.h | 6 | ||||
-rw-r--r-- | remote.c | 3 | ||||
-rw-r--r-- | svdrp.c | 4 | ||||
-rw-r--r-- | thread.c | 36 | ||||
-rw-r--r-- | thread.h | 7 | ||||
-rw-r--r-- | tools.c | 76 | ||||
-rw-r--r-- | tools.h | 13 | ||||
-rw-r--r-- | vdr.c | 19 |
37 files changed, 902 insertions, 276 deletions
diff --git a/CONTRIBUTORS b/CONTRIBUTORS index f1157b1..3a04af1 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -104,9 +104,10 @@ Stefan Huelswitt <huels@iname.com> for implementing backtracing for fast forward/rewind for implementing the replay mode display -Ulrich Röder <dynamite@efr-net.de> +Ulrich Röder <roeder@efr-net.de> for pointing out that there are channels that have a symbol rate higher than 27500 + for his support in keeping the Premiere World channels up to date in 'channels.conf' Helmut Schächner <schaechner@yahoo.com> for his support in keeping the Premiere World channels up to date in 'channels.conf' @@ -142,3 +143,10 @@ Andreas Vitting <Andreas@huji.de> Matthias Weingart <matthias@pentax.boerde.de> for fixing handling of the volume, mute and power keys when menus are active + for fixing the repeat function when using the LIRC remote control + +Andreas Share <a.share@t-online.de> + for his support in keeping the Premiere World channels up to date in 'channels.conf' + +Simon Bauschulte <SemiSchwabe@Brutzel.de> + for his support in keeping the Premiere World channels up to date in 'channels.conf' @@ -786,3 +786,47 @@ Video Disk Recorder Revision History at the expected time). - Made the volume, mute and power keys work when a menu is active, too (thanks to Matthias Weingart). + +2001-10-21: Version 0.97 + +- Implemented a lock file to prevent more than one instance of VDR from removing + files from the video directory at the same time. +- The new setup parameter SplitEditedFiles can be used to control whether or + not the result of an editing process shall be written into separate files. +- Fixed handling repeat function when using LIRC (thanks to Matthias Weingart). +- The shutdown program (defined with the '-s' option) now also gets the channel + number and recording title of the timer (see INSTALL). +- New channel data for 'Premiere One', 'Premiere X-Action', 'Fox Kids Türkce' + and 'N24' (thanks to Andreas Share, Ulrich Röder, Uwe Scheffler and Simon + Bauschulte). Note that if you are using the default 'channels.conf' or + 'channels.conf.cable' files you may need to check any exiting timers to see + whether they still use the correct channel number. +- Fixed the "EPG bugfix" (sometimes had duplicate information in Subtitle and + Extended Description). +- Fixed checking for valid video device when setting the video mode. +- The external command 'sort' is no longer required. VDR now sorts the list of + recordings itself, making sure that recordings that stem from repeating timers + are sorted chronologically. Sorting is done according to the setting of the + current locale, so you may want to make sure LC_COLLATE is set to the desired + value (see INSTALL). +- Fixed handling 'newline' characters in EPG texts (thanks to Rolf Hakenes for + an improved version of his 'libdtv'). + Newline characters are always mapped to a single "blank" in VDR, because they + would otherwise disturb the Title and Subtitle layout in the channel display + (where these are assumed to be single line texts) and would have to be + specially handled in the 'epg.data' file and the LSTE command in SVDRP. +- Mapping ` ("backtick") characters in EPG texts to ' (single quote). +- Fixed timers starting and ending at unexpected times. 'localtime()' was not + thread safe, now using localtime_r(). +- Removed the "system time seen..." message. +- Fixed a bug in the replay mode display when pressing the Green or Yellow + button while in trick mode (thanks to Stefan Huelswitt) +- Closing all open file descriptors when calling external programs. +- The menu timeout now also works when pressing the "Back" button during replay + to enter the "Recordings" menu. +- Updated 'channels.conf' for the "Bundesliga" channels of Premiere World + (thanks to Helmut Schächner). +- Fixed reading timers.conf and channels.conf that contain blanks after numeric + values. +- Fixed handling trick modes near the beginning and end of a recording. +- Pressing the "Back" button while replaying a DVD now leads to the DVD menu. @@ -90,6 +90,24 @@ option to set the controlling terminal, as in vdr:123:respawn:/usr/local/bin/vdr --terminal=/dev/tty8 -w 60 +Locale +------ + +When presenting the list of recordings, VDR sorts the entries according to +the current "locale" settings. This makes sure that special characters (like +the German "umlauts") appear at the expected positions. In order to benefit +from this you may have to set the locale environment variable, for instance + + export LANG=de_DE + +for a German locale. If you don't want this to result in German error messages +in the log file, it is sufficient to just set + + export LC_COLLATE=de_DE + +which only influences the way strings are sorted and leaves error messages +in English. + Automatic restart in case of hangups: ------------------------------------- @@ -109,7 +127,7 @@ active, the user has been inactive for at least MinUserInactivity minutes and the next timer event is at least MinEventTimeout minutes in the future (see the Setup parameters in MANUAL). -The command given in the '-s' option will be called with two parameters. +The command given in the '-s' option will be called with four parameters. The first one is the time (in UTC) of the next timer event (as a time_t type number), and the second one is the number of seconds from the current time until the next timer event. Your program can choose which one to use @@ -129,6 +147,12 @@ and only perform the system shutdown. A program that uses the second parameter to set the hardware for restart must therefore also check whether the first parameter is '0'. +The third parameter contains the number of the channel that will be recorded +by the next timer (or 0 if no timer is present), and the fourth parameter +contains the file name of the recording as defined in the timer (or an empty +string if no timer is present). These can be used by the shutdown program to +show that information on some display interface etc. + If a timer is currently recording, the parameters will reflect the start time of that timer. This means that the first parameter will be a time in the past, and the second parameter will be a negative number. This only @@ -8,7 +8,7 @@ Video Disk Recorder User's Manual possible, several keys have different meanings in the various modes: - Key Normal Main Channels Timers Edit/New Recordings Replay + Key Normal Main Channels Timers Edit/New Recordings Replay Up Ch up Crsr up Crsr up Crsr up Crsr up Crsr up Play Down Ch down Crsr down Crsr down Crsr down Crsr down Crsr down Pause @@ -386,7 +386,8 @@ Video Disk Recorder User's Manual 0 = no EPG fixing 1 = basic fixing of text location (Title, Subtitle and Extended Description) - 2 = removal of excess whitespace and hyphens + 2 = removal of excess whitespace and hyphens, mapping of + wrongly used characters 3 = fixing the date in timestamps between 00:00 and 06:00 (use with care - hopefully one day Pro7 and Kabel1 will learn how to read the clock/calender) @@ -449,6 +450,12 @@ Video Disk Recorder User's Manual you may want to use smaller values if you are planning on archiving a recording to CD. + SplitEditedFiles = 0 During the actual editing process VDR writes the result + into files that may grow up to MaxVideoFileSize. If you + prefer to have each marked sequence stored in a separate + file (named 001.vdr, 002.vdr, ...) you can set this + option to 1. + MinEventTimeout=30 If the command line option '-s' has been set, VDR will MinUserInactivity=120 automatically shutdown the computer if the next timer event is at least MinEventTimeout minutes in the future, @@ -4,7 +4,7 @@ # See the main source file 'vdr.c' for copyright information and # how to reach the author. # -# $Id: Makefile 1.27 2001/08/31 13:13:30 kls Exp $ +# $Id: Makefile 1.28 2001/10/07 15:14:50 kls Exp $ .DELETE_ON_ERROR: @@ -39,6 +39,8 @@ endif DEFINES += -DREMOTE_$(REMOTE) +DEFINES += -D_GNU_SOURCE + ifdef DEBUG_OSD DEFINES += -DDEBUG_OSD endif diff --git a/channels.conf b/channels.conf index 9c90491..200fbfe 100644 --- a/channels.conf +++ b/channels.conf @@ -24,7 +24,7 @@ Super RTL:12188:h:0:27500:165:120:65:0:12040 VOX:12188:h:0:27500:167:136:0:0:12060 DW TV:12363:v:0:27500:305:306:0:0:8905 Kabel 1:12480:v:0:27500:511:512:33:0:899 -tm3:12480:v:0:27500:767:768:0:0:897 +Neun Live:12480:v:0:27500:767:768:0:0:897 DSF:12480:v:0:27500:1023:1024:0:0:900 HOT:12480:v:0:27500:1279:1280:0:0:40 Bloomberg TV Germany:12551:v:0:22000:162:99:0:0:12160 @@ -52,9 +52,11 @@ Premiere World:11797:h:0:27500:255:256:32:0:8 Premiere 1:11797:h:0:27500:511:512:0:3:10 Premiere 2:11797:h:0:27500:1791:1792:0:3:11 Premiere 3:11797:h:0:27500:2303:2304:0:3:43 +Premiere One:12032:h:0:27500:3071:3072:0:3:51 Premiere Star:11797:h:0:27500:767:768:0:3:9 Premiere Sci-Fi:11797:h:0:27500:1535:1536:0:3:41 Premiere Action:11797:h:0:27500:1023:1024:0:3:20 +Premiere X-Action:11798:h:0:27500:2047:2048:0:3:50 Premiere Comedy:11797:h:0:27500:1279:1280:0:3:29 13th Street:12031:h:0:27500:2303:2304:0:3:42 Studio Universal:12090:V:0:27500:255:256:0:3:36 @@ -63,6 +65,7 @@ Heimatkanal:12031:h:0:27500:2815:2816:0:3:517 Discovery Channel:12031:h:0:27500:1791:1792:0:3:14 Planet:12090:V:0:27500:1279:1280:0:3:13 Fox Kids:12031:h:0:27500:1279:1280:0:3:28 +Fox Kids Türkce:11914:H:0:27500:767:768:8191:3:54 Junior:12031:h:0:27500:255:256:0:3:19 K-Toon:12031:h:0:27500:511:512:0:3:12 Disney Channel:12090:V:0:27500:767:768:0:3:34 @@ -93,6 +96,7 @@ Cinedom 5A:11758:h:0:27500:1279:1280:0:3:194 Cinedom 5B:11720:h:0:27500:1791:1792:0:3:177 Cinedom 5C:12070:h:0:27500:1023:1024:0:3:186 :Beta Digital +N24:11914:H:0:27500:255:256:8191:3:52 CNBC:12148:h:0:27500:255:256:0:3:35 Liberty TV.com:12610:V:0:22000:941:943,942:0:0:12199 :PW Erotic @@ -112,15 +116,15 @@ Verfolgerfeld:11720:h:0:27500:2303:2304:0:3:241 Cockpitkanal:11720:h:0:27500:2559:2560:0:3:242 Boxengasse:11720:h:0:27500:2047:2048:0:3:240 :Premiere World Bundesliga -Superdom:12070:h:0:27500:255:256:0:3:26 -Spiel 1:11719:h:0:27500:255:256,257:0:3:17 -Spiel 2:11719:h:0:27500:2047:2048,2049:0:3:240 -BuLi-Konferenz:12070:h:0:27500:3071:3072,3073:0:3:208 -BuLi-Spiel 1:12070:h:0:27500:3327:3328,3329:0:3:209 -BuLi-Spiel 2:12070:h:0:27500:2303:2304,2305:0:3:210 -BuLi-Spiel 3:12070:h:0:27500:3583:3584,3585:0:3:211 -BuLi-Spiel 4:12070:h:0:27500:2559:2560,2561:0:3:212 -BuLi-Spiel 5:12070:h:0:27500:2815:2816,2817:0:3:213 +Superdom:11758:h:0:27500:2815:8192:0:3:18 +BuLi-Konferenz:11758:h:0:27500:3071:3072,3073:0:3:215 +BuLi-Spiel 1:11719:h:0:27500:255:256,257:0:3:17 +BuLi-Spiel 2:11719:h:0:27500:2047:2048,2049:0:3:240 +BuLi-Spiel 3:11719:h:0:27500:3327:3328,3329:0:3:241 +BuLi-Spiel 4:11719:h:0:27500:2303:2304,2305:0:3:242 +BuLi-Spiel 5:11719:h:0:27500:3583:3584,3585:0:3:243 +BuLi-Spiel 6:11719:h:0:27500:2559:2560,2561:0:3:244 +BuLi-Spiel 7:11758:h:0:27500:2815:2816,2817:0:3:214 : TV Niepokalanow:11876:h:0:27500:305:321:0:0:20601 Mosaico:11934:v:0:27500:165:100:0:0:29010 diff --git a/channels.conf.cable b/channels.conf.cable index 60b3eb5..6e0f43b 100644 --- a/channels.conf.cable +++ b/channels.conf.cable @@ -1,54 +1,56 @@ :verschlüsselte Fernsehprogramm -PREMIERE 1:370:h:0:6900:511:512:0:1:10 -PREMIERE 2:370:h:0:6900:1791:1792:0:1:11 -PREMIERE 3:370:h:0:6900:2303:2304:0:1:43 -PREMIERE ACTION:370:h:0:6900:1023:1024:0:1:20 +PREMIERE ONE:378:h:0:6900:3071:3072:0:1:51 +PREMIERE MOVIE 1:370:h:0:6900:511:512:0:1:10 +PREMIERE MOVIE 2:370:h:0:6900:1791:1792:0:1:11 +PREMIERE MOVIE 3:370:h:0:6900:2303:2304:0:1:43 +PREMIERE ACTION:370:h:0:6900:1023:1024,1025:0:1:20 +PREMIERE X-ACTION:370:h:0:6900:2047:2048,2049:0:1:50 PREMIERE SCI-FI:370:h:0:6900:1535:1536:0:1:41 PREMIERE STAR:370:h:0:6900:767:768:0:1:9 PREMIERE COMEDY:370:h:0:6900:1279:1280:0:1:29 -13 TH STREET:378:h:0:6900:2303:2304:0:1:42 +13 TH STREET:378:h:0:6900:2303:2304,2305:0:1:42 KRIMI &CO:378:h:0:6900:1535:1536:0:1:23 STUDIO UNIVERSAL:402:h:0:6900:1050:1054:0:1:36 DISCOVERY CHANNEL:378:h:0:6900:1791:1792:0:1:14 +FILMPALAST:378:h:0:6900:2559:2560:0:1:516 DISNEY CHANNEL:402:h:0:6900:1030:1034:0:1:34 SUNSET:378:h:0:6900:1023:1024:0:1:16 PLANET:402:h:0:6900:1100:1104:0:1:13 -SEASONS:402:h:0:6900:1040:1044:0:1:33 CLASSICA:378:h:0:6900:767:768:0:1:15 GOLDSTAR TV:378:h:0:6900:3839:3840:0:1:518 -FILMPALAST:378:h:0:6900:2559:2560:0:1:516 HEIMATKANAL:378:h:0:6900:2815:2816:0:1:517 +K-TOON:378:h:0:6900:511:512:0:1:12 FOX KIDS:378:h:0:6900:1279:1280:0:1:28 +KiKa:394:h:0:6900:310:320:330:0:28008 JUNIOR:378:h:0:6900:255:256:0:1:19 -K-TOON:378:h:0:6900:12:13:0:1:12 :Fernsehprogramme -Das Erste:410:h:0:6900:101:102:104:0:28106 -ZDF:394:h:0:6900:110:120:130:0:28006 +Das Erste:410:h:0:6900:101:102,88:104:0:28106 +ZDF:394:h:0:6900:110:120,121:130:0:28006 ZDF.info:394:h:0:6900:610:620:0:0:28011 ZDF.doku:394:h:0:6900:660:670:0:0:28014 -ZDF Theaterkanal:394:h:0:6900:3440:3441:0:0:28016 +ZDF Theaterkanal:394:h:0:6900:1110:1120:130:0:28016 +EinsExtra:426:h:0:6900:101:102:0:0:28201 +EinsFestival:426:h:0:6900:201:202:0:0:28202 +EinsMuXx:426:h:0:6900:301:302:0:0:28203 3sat:394:h:0:6900:210:220:230:0:28007 -KiKa:394:h:0:6900:310:320:330:0:28008 +arte:410:h:0:6900:401:402:404:0:28109 EuroNews:394:h:0:6900:2221:2233:768:0:28015 +Phoenix:410:h:0:6900:901:902:0:0:28114 Eurosport:394:h:0:6900:410:420:430:0:28009 DW-tv:610:h:0:6900:634:632:0:0:6101 CNBC:394:h:0:6900:510:520:530:0:28010 -Test-R:410:h:0:6900:901:902:104:0:28130 -Bayerisches FS:410:h:0:6900:201:202:204:0:28107 WDR FERNSEHEN:410:h:0:6900:601:602:604:0:28111 -arte:410:h:0:6900:401:402:404:0:28109 +MDR FERNSEHEN:426:h:0:6900:401:402:404:0:28204 SR Fernsehen Suedwest:410:h:0:6900:501:502:504:0:28110 -hessen fernsehen:410:h:0:6900:301:302:304:0:28108 +SuedWest BW:410:h:0:6900:801:802:804:0:28113 +SuedWest RP:426:h:0:6900:3101:3102:3104:0:28231 BR-alpha:410:h:0:6900:701:702:704:0:28112 -SWR Fernsehen:410:h:0:6900:801:802:804:0:28113 -Phoenix:410:h:0:6900:901:902:0:0:28114 -EinsExtra:426:h:0:6900:101:102:0:0:28201 -EinsFestival:426:h:0:6900:201:202:0:0:28202 -EinsMuXx:426:h:0:6900:301:302:0:0:28203 -MDR FERNSEHEN:426:h:0:6900:401:402:404:0:28204 -ORB-Fernsehen:426:h:0:6900:501:502:504:0:28205 B1 Berlin:426:h:0:6900:601:602:604:0:28206 N3:426:h:0:6900:2401:2402:2404:0:28224 +ORB-Fernsehen:426:h:0:6900:501:502:504:0:28205 +hessen fernsehen:410:h:0:6900:301:302:304:0:28108 +Bayerisches FS:410:h:0:6900:201:202:204:0:28107 +Test-R:410:h:0:6900:901:902:104:0:28130 :Mediavision Extreme Sport:346:h:0:6900:801:802:0:1:50700 Bloomberg:346:h:0:6900:811:812:0:1:50701 @@ -60,6 +62,7 @@ Einstein:346:h:0:6900:623:624:0:1:50719 Leitseite:346:h:0:6900:2254:0:0:0:5004 Via 1 - Schöner Reisen:346:h:0:6900:611:612:0:0:50705 Parlamentsfernsehen:610:h:0:6900:33:36:47:0:6100 +Vh1 - Classic:610:h:0:6900:604:603:0:0:6106 :Diverse TV-Sender TV Polonia:434:h:0:6900:641:642:0:1:53204 Kanal D:434:h:0:6900:651:652:0:1:53205 @@ -68,18 +71,10 @@ ERT-Sat:434:h:0:6900:691:692:0:1:53209 CNE:434:h:0:6900:4056:4057:0:1:53208 ZEE TV:442:h:0:6900:517:773:0:1:53301 NTV i:442:h:0:6900:514:515:0:1:53302 -Leonardo:610:h:0:6900:653:652:0:1:6102 -Alice:610:h:0:6900:651:650:0:1:6103 -Nuvolari:610:h:0:6900:649:648:0:1:6104 ATV:434:h:0:6900:631:632:0:0:53203 -unknown:434:h:0:6900:2570:2571:0:0:18954 TW1:610:h:0:6900:6106:6107:0:0:6106 -unknown:346:h:0:6900:2930:2931:0:0:11122 -unknown:394:h:0:6900:1844:1845:0:1:59188 -unknown:410:h:0:6900:627:628:0:1:627 PREMIERE WORLD:370:h:0:6900:255:256:32:0:8 :Premiere World Bundesliga -SUPERDOM:386:h:0:6900:255:257:0:1:26 Superdom:362:h:0:6900:255:256:0:1:26 Spiel 1:362:h:0:6900:255:256,257:0:1:17 Spiel 2:362:h:0:6900:2047:2048,2049:0:1:240 @@ -90,9 +85,9 @@ BuLi-Spiel 3:362:h:0:6900:3583:3584,3585:0:1:211 BuLi-Spiel 4:362:h:0:6900:2559:2560,2561:0:1:212 BuLi-Spiel 5:362:h:0:6900:2815:2816,2817:0:1:213 :Premiere Sport -PR-SPORT 1:362:h:0:6900:255:256:0:1:17 -PR-SPORT 2:362:h:0:6900:3327:3328:0:1:27 -PR-SPORT 3:362:h:0:6900:2815:2816:0:1:18 +PREMIERE SPORT 1:362:h:0:6900:255:256:0:1:17 +PREMIERE SPORT 2:362:h:0:6900:3327:3328:0:1:27 +PREMIERE SPORT 3:354:h:0:6900:2815:2816:0:1:18 :Premiere Formel 1 F1 Studio:362:h:0:6900:255:256:0:1:17 F1 Box:362:h:0:6900:2047:2048:0:1:240 @@ -106,35 +101,40 @@ Cinedom 1B:386:h:0:6900:1535:1536,1537:0:1:178 Cinedom 1C:362:h:0:6900:511:512,513:0:1:180 Cinedom 1D:354:h:0:6900:511:512,513:0:1:190 :Premiere Cinedom 2 -Cinedom 2A:386:h:0:6900:1791:1792:0:1:179 -Cinedom 2B:362:h:0:6900:1279:1280:0:1:183 +Cinedom 2A:386:h:0:6900:1791:1792,1793:0:1:179 +Cinedom 2B:362:h:0:6900:1279:1280,1281:0:1:183 Cinedom 2C:386:h:0:6900:511:512:0:1:184 Cinedom 2D:386:h:0:6900:1279:1280:0:1:188 Cinedom 2E:354:h:0:6900:1023:1024:0:1:193 : Premiere Cinedom 3 -Cinedom 3A:362:h:0:6900:1023:1024:0:1:182 +Cinedom 3A:362:h:0:6900:1023:1024,1025:0:1:182 Cinedom 3B:386:h:0:6900:767:768:0:1:185 Cinedom 3C:354:h:0:6900:2559:2560:0:1:192 Cinedom 3D:354:h:0:6900:1535:1536:0:1:195 : Premiere Cinedom 4 -Cinedom 4A:362:h:0:6900:767:768:0:1:181 +Cinedom 4A:362:h:0:6900:767:768,769:0:1:181 Cinedom 4B:386:h:0:6900:2047:2048:0:1:187 Cinedom 4C:354:h:0:6900:767:768:0:1:191 : Premiere Cinedom 5 -Cinedom 5A:386:h:0:6900:1023:1024:0:1:186 -Cinedom 5B:354:h:0:6900:1279:1280:0:1:194 +Cinedom 5A:386:h:0:6900:1023:1024,1025:0:1:186 +Cinedom 5B:354:h:0:6900:1279:1280,1281:0:1:194 : Premiere Cinedom Deluxe -CINEDOM DELUXE:354:h:0:6900:255:256,257;259:0:1:189 +CINEDOM DELUXE:354:h:0:6900:255:256,257:0:1:189 :Premiere Erotic BEATE-UHSE.TV:354:h:0:6900:3839:3840:0:1:21 BLUE MOVIE 1:354:h:0:6900:1791:1792:0:1:513 BLUE MOVIE 2:354:h:0:6900:2047:2048:0:1:514 BLUE MOVIE 3:354:h:0:6900:2303:2304:0:1:515 :Radioprogramme -100,6:354:h:0:6900:0:1312:0:0:161 +Fritz:426:h:0:6900:0:901:0:0:28209 +HR XXL:410:h:0:6900:0:3501:0:0:28125 +JUMP:426:h:0:6900:0:1001:0:0:28210 +SPUTNIK:426:h:0:6900:0:1201:0:0:28212 +RADIOmultikulti:426:h:0:6900:0:1301:0:0:28213 DLR-Berlin:394:h:0:6900:0:710:0:0:28012 DLF-Köln:394:h:0:6900:0:810:0:0:28013 Österreich 1:394:h:0:6900:0:169:0:0:28017 +100,6:354:h:0:6900:0:1312:0:0:161 Bayern 4 Klassik:410:h:0:6900:0:3001:0:0:28120 B5 aktuell:410:h:0:6900:0:3101:0:0:28121 Bremen 2:410:h:0:6900:0:3801:0:0:28128 @@ -143,47 +143,42 @@ NDR 4 Info:410:h:0:6900:0:3701:0:0:28127 SR 1:410:h:0:6900:0:3901:0:0:28129 hr-klassik:410:h:0:6900:0:3401:0:0:28124 hr2:410:h:0:6900:0:3301:0:0:28123 -HR XXL:410:h:0:6900:0:3501:0:0:28125 hr-chronos:410:h:0:6900:0:3201:0:0:28122 Radio 3:426:h:0:6900:0:701:0:0:28207 MDR KULTUR:426:h:0:6900:0:801:0:0:28208 -Fritz:426:h:0:6900:0:901:0:0:28209 -JUMP:426:h:0:6900:0:1001:0:0:28210 MDR info:426:h:0:6900:0:1101:0:0:28211 -SPUTNIK:426:h:0:6900:0:1201:0:0:28212 -RADIOmultikulti:426:h:0:6900:0:1301:0:0:28213 SWR-2:426:h:0:6900:0:1401:0:0:28214 WDR3:426:h:0:6900:0:1501:0:0:28215 WDR Radio 5:426:h:0:6900:0:1601:0:0:28216 :verschlüsselte Radioprogramme -KLASSIK POPULÄR:378:h:0:6900:0:592:0:1:145 -KLASS. SYMPHONIEN:378:h:0:6900:0:608:0:1:146 -OPER & VOKALMUSIK:378:h:0:6900:0:624:0:1:147 -BAROCKMUSIK:378:h:0:6900:0:640:0:1:148 -JAZZ:378:h:0:6900:0:656:0:1:149 -HITLISTE:378:h:0:6900:0:784:0:1:150 -ALTERNATIVE ROCK:378:h:0:6900:0:800:0:1:151 -DANCE:378:h:0:6900:0:816:0:1:152 -COUNTRY:378:h:0:6900:0:352:0:1:153 -CLASSIC ROCK:378:h:0:6900:0:544:0:1:154 -FILMMUSIK:378:h:0:6900:0:368:0:1:155 -DEUTSCHE HITS:402:h:0:6900:0:1156:0:1:156 -SOUL CLASSICS:402:h:0:6900:0:1161:0:1:157 -TÜRK MÜZIGI:402:h:0:6900:0:1166:0:1:158 -GOLD:402:h:0:6900:0:1171:0:1:159 -EASY LISTENING:402:h:0:6900:0:1201:0:1:162 -LOVE SONGS:402:h:0:6900:0:1191:0:1:163 -MUSICALS:402:h:0:6900:0:1196:0:1:164 -OLD GOLD:402:h:0:6900:0:1186:0:1:165 -SCHLAGER:402:h:0:6900:0:1176:0:1:166 -VOLKSMUSIK:402:h:0:6900:0:1181:0:1:167 -All Jazz:442:h:0:6900:0:535:0:1:53350 -Cristal New Age:442:h:0:6900:0:536:0:0:53351 -Movie Sounds:442:h:0:6900:0:537:0:1:53352 -Sinfonica:442:h:0:6900:0:538:0:1:53353 -Opernfestival:442:h:0:6900:0:539:0:1:53354 -Barock Fantasie:442:h:0:6900:0:540:0:1:53355 -Musica Camerata:442:h:0:6900:0:541:0:1:53356 -Musica Antica:442:h:0:6900:0:542:0:1:53357 -Adagio:442:h:0:6900:0:543:0:1:53358 -Jazz Legends:442:h:0:6900:0:544:0:1:53359 +ALTERNATIVE ROCK:378:h:0:6900:1:800:0:1:151 +HITLISTE:378:h:0:6900:1:784:0:1:150 +DANCE:378:h:0:6900:1:816:0:1:152 +EASY LISTENING:402:h:0:6900:1:1201:0:1:162 +CLASSIC ROCK:378:h:0:6900:1:544:0:1:154 +Cristal New Age:442:h:0:6900:1:536:0:0:53351 +Movie Sounds:442:h:0:6900:1:537:0:1:53352 +LOVE SONGS:402:h:0:6900:1:1191:0:1:163 +KLASSIK POPULÄR:378:h:0:6900:1:592:0:1:145 +KLASS. SYMPHONIEN:378:h:0:6900:1:608:0:1:146 +OPER & VOKALMUSIK:378:h:0:6900:1:624:0:1:147 +BAROCKMUSIK:378:h:0:6900:1:640:0:1:148 +JAZZ:378:h:0:6900:1:656:0:1:149 +COUNTRY:378:h:0:6900:1:352:0:1:153 +FILMMUSIK:378:h:0:6900:1:368:0:1:155 +DEUTSCHE HITS:402:h:0:6900:1:1156:0:1:156 +SOUL CLASSICS:402:h:0:6900:1:1161:0:1:157 +TÜRK MÜZIGI:402:h:0:6900:1:1166:0:1:158 +GOLD:402:h:0:6900:1:1171:0:1:159 +MUSICALS:402:h:0:6900:1:1196:0:1:164 +OLD GOLD:402:h:0:6900:1:1186:0:1:165 +SCHLAGER:402:h:0:6900:1:1176:0:1:166 +VOLKSMUSIK:402:h:0:6900:1:1181:0:1:167 +All Jazz:442:h:0:6900:1:535:0:1:53350 +Sinfonica:442:h:0:6900:1:538:0:1:53353 +Opernfestival:442:h:0:6900:1:539:0:1:53354 +Barock Fantasie:442:h:0:6900:1:540:0:1:53355 +Musica Camerata:442:h:0:6900:1:541:0:1:53356 +Musica Antica:442:h:0:6900:1:542:0:1:53357 +Adagio:442:h:0:6900:1:543:0:1:53358 +Jazz Legends:442:h:0:6900:1:544:0:1:53359 @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: config.c 1.73 2001/09/22 13:36:59 kls Exp $ + * $Id: config.c 1.76 2001/10/20 13:09:38 kls Exp $ */ #include "config.h" @@ -14,6 +14,10 @@ #include "i18n.h" #include "interface.h" +// IMPORTANT NOTE: in the 'sscanf()' calls there is a blank after the '%d' +// format characters in order to allow any number of blanks after a numeric +// value! + // -- cKeys ------------------------------------------------------------------ tKey keyTable[] = { // "Up" and "Down" must be the first two keys! @@ -251,16 +255,16 @@ bool cChannel::Parse(const char *s) else { groupSep = false; char *apidbuf = NULL; - int fields = sscanf(s, "%a[^:]:%d:%c:%d:%d:%d:%a[^:]:%d:%d:%d", &buffer, &frequency, &polarization, &diseqc, &srate, &vpid, &apidbuf, &tpid, &ca, &pnr); + int fields = sscanf(s, "%a[^:]:%d :%c:%d :%d :%d :%a[^:]:%d :%d :%d ", &buffer, &frequency, &polarization, &diseqc, &srate, &vpid, &apidbuf, &tpid, &ca, &pnr); apid1 = apid2 = 0; dpid1 = dpid2 = 0; if (apidbuf) { char *p = strchr(apidbuf, ';'); if (p) *p++ = 0; - sscanf(apidbuf, "%d,%d", &apid1, &apid2); + sscanf(apidbuf, "%d ,%d ", &apid1, &apid2); if (p) - sscanf(p, "%d,%d", &dpid1, &dpid2); + sscanf(p, "%d ,%d ", &dpid1, &dpid2); delete apidbuf; } else @@ -324,7 +328,8 @@ cTimer::cTimer(bool Instant) cChannel *ch = Channels.GetByNumber(cDvbApi::CurrentChannel()); channel = ch ? ch->number : 0; time_t t = time(NULL); - struct tm *now = localtime(&t); + struct tm tm_r; + struct tm *now = localtime_r(&t, &tm_r); day = now->tm_mday; start = now->tm_hour * 100 + now->tm_min; stop = start + 200; // "instant recording" records 2 hours by default @@ -349,10 +354,11 @@ cTimer::cTimer(const cEventInfo *EventInfo) time_t tstart = EventInfo->GetTime(); time_t tstop = tstart + EventInfo->GetDuration() + Setup.MarginStop * 60; tstart -= Setup.MarginStart * 60; - struct tm *time = localtime(&tstart); + struct tm tm_r; + struct tm *time = localtime_r(&tstart, &tm_r); day = time->tm_mday; start = time->tm_hour * 100 + time->tm_min; - time = localtime(&tstop); + time = localtime_r(&tstop, &tm_r); stop = time->tm_hour * 100 + time->tm_min; if (stop >= 2400) stop -= 2400; @@ -466,7 +472,7 @@ bool cTimer::Parse(const char *s) strcat(strn0cpy(s2, s, l2 + 1), " \n"); s = s2; } - if (8 <= sscanf(s, "%d:%d:%a[^:]:%d:%d:%d:%d:%a[^:\n]:%a[^\n]", &active, &channel, &buffer1, &start, &stop, &priority, &lifetime, &buffer2, &summary)) { + if (8 <= sscanf(s, "%d :%d :%a[^:]:%d :%d :%d :%d :%a[^:\n]:%a[^\n]", &active, &channel, &buffer1, &start, &stop, &priority, &lifetime, &buffer2, &summary)) { if (summary && !*skipspace(summary)) { delete summary; summary = NULL; @@ -497,12 +503,14 @@ bool cTimer::IsSingleEvent(void) int cTimer::GetMDay(time_t t) { - return localtime(&t)->tm_mday; + struct tm tm_r; + return localtime_r(&t, &tm_r)->tm_mday; } int cTimer::GetWDay(time_t t) { - int weekday = localtime(&t)->tm_wday; + struct tm tm_r; + int weekday = localtime_r(&t, &tm_r)->tm_wday; return weekday == 0 ? 6 : weekday - 1; // we start with monday==0! } @@ -513,7 +521,8 @@ bool cTimer::DayMatches(time_t t) time_t cTimer::IncDay(time_t t, int Days) { - tm tm = *localtime(&t); + struct tm tm_r; + tm tm = *localtime_r(&t, &tm_r); tm.tm_mday += Days; // now tm_mday may be out of its valid range int h = tm.tm_hour; // save original hour to compensate for DST change t = mktime(&tm); // normalize all values @@ -523,7 +532,8 @@ time_t cTimer::IncDay(time_t t, int Days) time_t cTimer::SetTime(time_t t, int SecondsFromMidnight) { - tm tm = *localtime(&t); + struct tm tm_r; + tm tm = *localtime_r(&t, &tm_r); tm.tm_hour = SecondsFromMidnight / 3600; tm.tm_min = (SecondsFromMidnight % 3600) / 60; tm.tm_sec = SecondsFromMidnight % 60; @@ -803,6 +813,7 @@ cSetup::cSetup(void) OSDheight = 18; OSDMessageTime = 1; MaxVideoFileSize = MAXVIDEOFILESIZE; + SplitEditedFiles = 0; MinEventTimeout = 30; MinUserInactivity = 120; MultiSpeedMode = 0; @@ -843,6 +854,7 @@ bool cSetup::Parse(char *s) else if (!strcasecmp(Name, "OSDheight")) OSDheight = atoi(Value); else if (!strcasecmp(Name, "OSDMessageTime")) OSDMessageTime = atoi(Value); else if (!strcasecmp(Name, "MaxVideoFileSize")) MaxVideoFileSize = atoi(Value); + else if (!strcasecmp(Name, "SplitEditedFiles")) SplitEditedFiles = atoi(Value); else if (!strcasecmp(Name, "MinEventTimeout")) MinEventTimeout = atoi(Value); else if (!strcasecmp(Name, "MinUserInactivity")) MinUserInactivity = atoi(Value); else if (!strcasecmp(Name, "MultiSpeedMode")) MultiSpeedMode = atoi(Value); @@ -918,6 +930,7 @@ bool cSetup::Save(const char *FileName) fprintf(f, "OSDheight = %d\n", OSDheight); fprintf(f, "OSDMessageTime = %d\n", OSDMessageTime); fprintf(f, "MaxVideoFileSize = %d\n", MaxVideoFileSize); + fprintf(f, "SplitEditedFiles = %d\n", SplitEditedFiles); fprintf(f, "MinEventTimeout = %d\n", MinEventTimeout); fprintf(f, "MinUserInactivity = %d\n", MinUserInactivity); fprintf(f, "MultiSpeedMode = %d\n", MultiSpeedMode); @@ -4,13 +4,12 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: config.h 1.81 2001/09/22 13:37:05 kls Exp $ + * $Id: config.h 1.84 2001/10/07 15:13:23 kls Exp $ */ #ifndef __CONFIG_H #define __CONFIG_H -#define _GNU_SOURCE #include <stdio.h> #include <string.h> #include <time.h> @@ -19,7 +18,7 @@ #include "eit.h" #include "tools.h" -#define VDRVERSION "0.96" +#define VDRVERSION "0.97" #define MAXPRIORITY 99 #define MAXLIFETIME 99 @@ -298,6 +297,7 @@ public: int OSDwidth, OSDheight; int OSDMessageTime; int MaxVideoFileSize; + int SplitEditedFiles; int MinEventTimeout, MinUserInactivity; int MultiSpeedMode; int ShowReplayMode; @@ -7,7 +7,7 @@ * DVD support initially written by Andreas Schultz <aschultz@warp10.net> * based on dvdplayer-0.5 by Matjaz Thaler <matjaz.thaler@guest.arnes.si> * - * $Id: dvbapi.c 1.129 2001/09/23 13:44:27 kls Exp $ + * $Id: dvbapi.c 1.132 2001/10/21 13:36:27 kls Exp $ */ //#define DVDDEBUG 1 @@ -72,6 +72,9 @@ extern "C" { // is broken: #define MAXBROKENTIMEOUT 30 // seconds +// The maximum time to wait before giving up while catching up on an index file: +#define MAXINDEXCATCHUP 2 // seconds + #define CHECK(s) { if ((s) < 0) LOG_ERROR; } // used for 'ioctl()' calls #define FATALERRNO (errno != EAGAIN && errno != EINTR) @@ -108,14 +111,14 @@ private: int size, last; tIndex *index; cResumeFile resumeFile; - bool CatchUp(void); + bool CatchUp(int Index = -1); public: cIndexFile(const char *FileName, bool Record); ~cIndexFile(); bool Ok(void) { return index != NULL; } void Write(uchar PictureType, uchar FileNumber, int FileOffset); bool Get(int Index, uchar *FileNumber, int *FileOffset, uchar *PictureType = NULL, int *Length = NULL); - int GetNextIFrame(int Index, bool Forward, uchar *FileNumber = NULL, int *FileOffset = NULL, int *Length = NULL); + int GetNextIFrame(int Index, bool Forward, uchar *FileNumber = NULL, int *FileOffset = NULL, int *Length = NULL, bool StayOffEnd = false); int Get(uchar FileNumber, int FileOffset); int Last(void) { CatchUp(); return last; } int GetResume(void) { return resumeFile.Read(); } @@ -199,42 +202,48 @@ cIndexFile::~cIndexFile() delete fileName; } -bool cIndexFile::CatchUp(void) +bool cIndexFile::CatchUp(int Index) { if (index && f >= 0) { - struct stat buf; - if (fstat(f, &buf) == 0) { - int newLast = buf.st_size / sizeof(tIndex) - 1; - if (newLast > last) { - if (size <= newLast) { - size *= 2; - if (size <= newLast) - size = newLast + 1; - } - index = (tIndex *)realloc(index, size * sizeof(tIndex)); - if (index) { - int offset = (last + 1) * sizeof(tIndex); - int delta = (newLast - last) * sizeof(tIndex); - if (lseek(f, offset, SEEK_SET) == offset) { - if (safe_read(f, &index[last + 1], delta) != delta) { - esyslog(LOG_ERR, "ERROR: can't read from index"); - delete index; - index = NULL; - close(f); - f = -1; - } - last = newLast; - return true; - } - else - LOG_ERROR; - } - else - esyslog(LOG_ERR, "ERROR: can't realloc() index"); - } - } - else - LOG_ERROR; + for (int i = 0; i <= MAXINDEXCATCHUP && (Index < 0 || Index >= last); i++) { + struct stat buf; + if (fstat(f, &buf) == 0) { + int newLast = buf.st_size / sizeof(tIndex) - 1; + if (newLast > last) { + if (size <= newLast) { + size *= 2; + if (size <= newLast) + size = newLast + 1; + } + index = (tIndex *)realloc(index, size * sizeof(tIndex)); + if (index) { + int offset = (last + 1) * sizeof(tIndex); + int delta = (newLast - last) * sizeof(tIndex); + if (lseek(f, offset, SEEK_SET) == offset) { + if (safe_read(f, &index[last + 1], delta) != delta) { + esyslog(LOG_ERR, "ERROR: can't read from index"); + delete index; + index = NULL; + close(f); + f = -1; + break; + } + last = newLast; + } + else + LOG_ERROR; + } + else + esyslog(LOG_ERR, "ERROR: can't realloc() index"); + } + } + else + LOG_ERROR; + if (Index >= last) + sleep(1); + else + return true; + } } return false; } @@ -256,7 +265,7 @@ void cIndexFile::Write(uchar PictureType, uchar FileNumber, int FileOffset) bool cIndexFile::Get(int Index, uchar *FileNumber, int *FileOffset, uchar *PictureType, int *Length) { if (index) { - CatchUp(); + CatchUp(Index); if (Index >= 0 && Index <= last) { *FileNumber = index[Index].number; *FileOffset = index[Index].offset; @@ -276,7 +285,7 @@ bool cIndexFile::Get(int Index, uchar *FileNumber, int *FileOffset, uchar *Pictu return false; } -int cIndexFile::GetNextIFrame(int Index, bool Forward, uchar *FileNumber, int *FileOffset, int *Length) +int cIndexFile::GetNextIFrame(int Index, bool Forward, uchar *FileNumber, int *FileOffset, int *Length, bool StayOffEnd) { if (index) { if (Forward) @@ -284,7 +293,7 @@ int cIndexFile::GetNextIFrame(int Index, bool Forward, uchar *FileNumber, int *F int d = Forward ? 1 : -1; for (;;) { Index += d; - if (Index >= 0 && Index <= last) { + if (Index >= 0 && Index < last - ((Forward && StayOffEnd) ? 100 : 0)) { if (index[Index].type == I_FRAME) { if (FileNumber) *FileNumber = index[Index].number; @@ -1049,17 +1058,26 @@ void cReplayBuffer::Input(void) if (playMode == pmFast || (playMode == pmSlow && playDir == pdBackward)) { uchar FileNumber; int FileOffset, Length; - int Index = index->GetNextIFrame(readIndex, playDir == pdForward, &FileNumber, &FileOffset, &Length); + int Index = index->GetNextIFrame(readIndex, playDir == pdForward, &FileNumber, &FileOffset, &Length, true); if (Index >= 0) { if (!NextFile(FileNumber, FileOffset)) break; } else { - Play(); + // can't call Play() here, because those functions may only be + // called from the foreground thread - and we also don't need + // to empty the buffer here + CHECK(ioctl(audioDev, AUDIO_SET_AV_SYNC, true)); + CHECK(ioctl(videoDev, VIDEO_CONTINUE)); + playMode = pmPlay; + playDir = pdForward; continue; } readIndex = Index; r = ReadFrame(replayFile, b, Length, sizeof(b)); + // must call StripAudioPackets() here because the buffer is not emptied + // when falling back from "fast forward" to "play" (see above) + StripAudioPackets(b, r); } else if (index) { uchar FileNumber; @@ -1205,17 +1223,11 @@ void cReplayBuffer::SkipSeconds(int Seconds) Empty(true); int Index = writeIndex; if (Index >= 0) { - if (Seconds < 0) { - int sec = index->Last() / FRAMESPERSEC; - if (Seconds < -sec) - Seconds = -sec; - } - Index += Seconds * FRAMESPERSEC; - if (Index < 0) - Index = 1; // not '0', to allow GetNextIFrame() below to work! - uchar FileNumber; - int FileOffset; - readIndex = writeIndex = index->GetNextIFrame(Index, false, &FileNumber, &FileOffset) - 1; // Input() will first increment it! + Index = max(Index + Seconds * FRAMESPERSEC, 0); + if (Index > 0) + Index = index->GetNextIFrame(Index, false, NULL, NULL, NULL, true); + if (Index >= 0) + readIndex = writeIndex = Index - 1; // Input() will first increment it! } Empty(false); Play(); @@ -1250,9 +1262,9 @@ void cReplayBuffer::GetIndex(int &Current, int &Total, bool SnapToIFrame) { if (index) { if (playMode == pmStill) - Current = readIndex; + Current = max(readIndex, 0); else { - Current = writeIndex; + Current = max(writeIndex, 0); if (SnapToIFrame) { int i1 = index->GetNextIFrame(Current + 1, false); int i2 = index->GetNextIFrame(Current, true); @@ -2392,6 +2404,12 @@ void cCuttingBuffer::Action(void) Index = Mark->position; Mark = fromMarks.Next(Mark); CurrentFileNumber = 0; // triggers SetOffset before reading next frame + if (Setup.SplitEditedFiles) { + toFile = toFileName->NextFile(); + if (toFile < 0) + break; + FileSize = 0; + } } // the 'else' case (i.e. 'final end mark reached') is handled above // in 'Write one frame', so that the edited version will end right @@ -3163,7 +3181,7 @@ void cDvbApi::SetModeNormal(bool FromRecording) void cDvbApi::SetVideoFormat(videoFormat_t Format) { - if (fd_video) + if (fd_video >= 0) CHECK(ioctl(fd_video, VIDEO_SET_FORMAT, Format)); } @@ -16,7 +16,7 @@ * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * - * $Id: eit.c 1.24 2001/09/22 13:07:21 kls Exp $ + * $Id: eit.c 1.28 2001/10/19 13:13:25 kls Exp $ ***************************************************************************/ #include "eit.h" @@ -126,7 +126,8 @@ bool cMJD::SetSystemTime() struct tm *ptm; time_t loctim; - ptm = localtime(&mjdtime); + struct tm tm_r; + ptm = localtime_r(&mjdtime, &tm_r); loctim = time(NULL); if (abs(mjdtime - loctim) > 2) @@ -240,7 +241,8 @@ const char * cEventInfo::GetDate() const { static char szDate[25]; - strftime(szDate, sizeof(szDate), "%d.%m.%Y", localtime(&tTime)); + struct tm tm_r; + strftime(szDate, sizeof(szDate), "%d.%m.%Y", localtime_r(&tTime, &tm_r)); return szDate; } @@ -249,7 +251,8 @@ const char * cEventInfo::GetTimeString() const { static char szTime[25]; - strftime(szTime, sizeof(szTime), "%R", localtime(&tTime)); + struct tm tm_r; + strftime(szTime, sizeof(szTime), "%R", localtime_r(&tTime, &tm_r)); return szTime; } @@ -259,7 +262,8 @@ const char * cEventInfo::GetEndTimeString() const static char szEndTime[25]; time_t tEndTime = tTime + lDuration; - strftime(szEndTime, sizeof(szEndTime), "%R", localtime(&tEndTime)); + struct tm tm_r; + strftime(szEndTime, sizeof(szEndTime), "%R", localtime_r(&tEndTime, &tm_r)); return szEndTime; } @@ -337,6 +341,12 @@ void cEventInfo::Dump(FILE *f, const char *Prefix) const void cEventInfo::FixEpgBugs(void) { + // VDR can't usefully handle newline characters in the EPG data, so let's + // always convert them to blanks (independent of the setting of EPGBugfixLevel): + strreplace(pTitle, '\n', ' '); + strreplace(pSubtitle, '\n', ' '); + strreplace(pExtendedDescription, '\n', ' '); + if (Setup.EPGBugfixLevel == 0) return; @@ -395,7 +405,6 @@ void cEventInfo::FixEpgBugs(void) pSubtitle = NULL; } } - } // Pro7 sometimes repeats the Title in the Subtitle: // @@ -445,6 +454,13 @@ void cEventInfo::FixEpgBugs(void) } } + // Some channels use the ` ("backtick") character, where a ' (single quote) + // would be normally used. Actually, "backticks" in normal text don't make + // much sense, so let's replace them: + strreplace(pTitle, '`', '\''); + strreplace(pSubtitle, '`', '\''); + strreplace(pExtendedDescription, '`', '\''); + if (Setup.EPGBugfixLevel <= 2) return; @@ -455,10 +471,12 @@ void cEventInfo::FixEpgBugs(void) // correctly on the ASTRA satellite system. if (uServiceID == 898 // Pro-7 || uServiceID == 899) { // Kabel 1 - tm *t = localtime(&tTime); + struct tm tm_r; + tm *t = localtime_r(&tTime, &tm_r); if (t->tm_hour * 3600 + t->tm_min * 60 + t->tm_sec <= 6 * 3600) tTime += 24 * 3600; } + } } // --- cSchedule ------------------------------------------------------------- @@ -873,7 +891,8 @@ void cSIProcessor::Action() if (masterSIProcessor) { time_t now = time(NULL); - struct tm *ptm = localtime(&now); + struct tm tm_r; + struct tm *ptm = localtime_r(&now, &tm_r); if (now - lastCleanup > 3600 && ptm->tm_hour == 5) { LOCK_THREAD; @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: i18n.c 1.43 2001/09/16 14:43:05 kls Exp $ + * $Id: i18n.c 1.44 2001/09/30 11:31:43 kls Exp $ * * Slovenian translations provided by Miha Setina <mihasetina@softhome.net> * Italian translations provided by Alberto Carraro <bertocar@tin.it> @@ -929,6 +929,15 @@ const tPhrase Phrases[] = { "", // TODO "", // TODO }, + { "SplitEditedFiles", + "Editierte Dateien zerteilen", + "", // TODO + "", // TODO + "", // TODO + "", // TODO + "", // TODO + "", // TODO + }, { "MinEventTimeout", "Mindest Event Pause", "", // TODO diff --git a/libdtv/Makefile b/libdtv/Makefile index 50a1400..56cb533 100644 --- a/libdtv/Makefile +++ b/libdtv/Makefile @@ -4,9 +4,9 @@ ### ### ############################################################## -## $Revision: 1.1 $ -## $Date: 2001/06/25 12:53:00 $ -## $Author: kls $ +## $Revision: 1.3 $ +## $Date: 2001/06/25 12:51:41 $ +## $Author: hakenes $ ## ## (C) 2001 Rolf Hakenes <hakenes@hippomi.de>, under the GNU GPL. ## diff --git a/libdtv/liblx/Makefile b/libdtv/liblx/Makefile index a8034de..2531708 100644 --- a/libdtv/liblx/Makefile +++ b/libdtv/liblx/Makefile @@ -4,9 +4,9 @@ ### ### ############################################################## -## $Revision: 1.1 $ -## $Date: 2001/06/26 07:18:42 $ -## $Author: kls $ +## $Revision: 1.2 $ +## $Date: 2001/06/25 19:39:00 $ +## $Author: hakenes $ ## ## (C) 2001 Rolf Hakenes <hakenes@hippomi.de>, under the GNU GPL. ## diff --git a/libdtv/liblx/liblx.h b/libdtv/liblx/liblx.h index f2527e7..26ea664 100644 --- a/libdtv/liblx/liblx.h +++ b/libdtv/liblx/liblx.h @@ -4,9 +4,9 @@ /// /// ////////////////////////////////////////////////////////////// -// $Revision: 1.1 $ -// $Date: 2001/06/26 07:18:42 $ -// $Author: kls $ +// $Revision: 1.2 $ +// $Date: 2001/06/25 19:39:00 $ +// $Author: hakenes $ // // (C) 1992-2001 Rolf Hakenes <hakenes@hippomi.de>, under the GNU GPL. // diff --git a/libdtv/liblx/xListFuncs.c b/libdtv/liblx/xListFuncs.c index 34df7a8..7457170 100644 --- a/libdtv/liblx/xListFuncs.c +++ b/libdtv/liblx/xListFuncs.c @@ -6,7 +6,7 @@ // $Revision: 1.1 $ // $Date: 2001/06/25 12:29:47 $ -// $Author: kls $ +// $Author: hakenes $ // // (C) 1992-2001 Rolf Hakenes <hakenes@hippomi.de>, under the GNU GPL. // diff --git a/libdtv/liblx/xMemMgt.c b/libdtv/liblx/xMemMgt.c index 363ee4a..8f619bc 100644 --- a/libdtv/liblx/xMemMgt.c +++ b/libdtv/liblx/xMemMgt.c @@ -6,7 +6,7 @@ // $Revision: 1.1 $ // $Date: 2001/06/25 12:29:47 $ -// $Author: kls $ +// $Author: hakenes $ // // (C) 1992-2001 Rolf Hakenes <hakenes@hippomi.de>, under the GNU GPL. // diff --git a/libdtv/libsi/Makefile b/libdtv/libsi/Makefile index 4b939b9..38bff93 100644 --- a/libdtv/libsi/Makefile +++ b/libdtv/libsi/Makefile @@ -4,9 +4,9 @@ ### ### ############################################################## -## $Revision: 1.1 $ -## $Date: 2001/08/15 14:47:22 $ -## $Author: kls $ +## $Revision: 1.4 $ +## $Date: 2001/10/07 10:24:46 $ +## $Author: hakenes $ ## ## (C) 2001 Rolf Hakenes <hakenes@hippomi.de>, under the GNU GPL. ## @@ -80,4 +80,4 @@ $(SILIB) : $(OBJS) @echo compiling $<... @$(CC) $(DEFINES) $(CFLAGS) $(INCDIRS) -c $< -include Makefile.dep +-include Makefile.dep diff --git a/libdtv/libsi/include/libsi.h b/libdtv/libsi/include/libsi.h index 3790ae1..dda2b1e 100644 --- a/libdtv/libsi/include/libsi.h +++ b/libdtv/libsi/include/libsi.h @@ -4,9 +4,9 @@ /// /// ////////////////////////////////////////////////////////////// -// $Revision: 1.1 $ -// $Date: 2001/06/26 07:18:43 $ -// $Author: kls $ +// $Revision: 1.4 $ +// $Date: 2001/10/07 10:24:46 $ +// $Author: hakenes $ // // (C) 2001 Rolf Hakenes <hakenes@hippomi.de>, under the GNU GPL. // @@ -288,18 +288,20 @@ struct PidInfo { } while (0) -#define STREAMTYPE_ISO_VIDEO 1 +#define STREAMTYPE_11172_VIDEO 1 #define STREAMTYPE_13818_VIDEO 2 #define STREAMTYPE_11172_AUDIO 3 #define STREAMTYPE_13818_AUDIO 4 -#define STREAMTYPE_VIDEOTEXT 6 -#define STREAMTYPE_13522_MPEG 7 -#define STREAMTYPE_ITU_222 8 -#define STREAMTYPE_13818_A 9 -#define STREAMTYPE_13818_B 10 -#define STREAMTYPE_13818_C 11 -#define STREAMTYPE_13818_D 12 -#define STREAMTYPE_13818_AUX 13 +#define STREAMTYPE_13818_PRIVATE 5 +#define STREAMTYPE_13818_PES_PRIVATE 6 +#define STREAMTYPE_13522_MHPEG 7 +#define STREAMTYPE_13818_DSMCC 8 +#define STREAMTYPE_ITU_222_1 9 +#define STREAMTYPE_13818_A 10 +#define STREAMTYPE_13818_B 11 +#define STREAMTYPE_13818_C 12 +#define STREAMTYPE_13818_D 13 +#define STREAMTYPE_13818_AUX 14 /* Descriptors */ @@ -331,6 +333,58 @@ struct Iso639LanguageDescriptor { } while (0) +/* Ac3Descriptor */ + +#define AC3_TYPE_FLAG 0x0001 +#define BS_ID_FLAG 0x0002 +#define MAIN_ID_FLAG 0x0004 +#define ASVC_FLAG 0x0008 + +struct Ac3Descriptor { + struct NODE Node; + unsigned short Tag; + unsigned short PresentFlags; + unsigned short Ac3Type; + unsigned short BsId; + unsigned short MainId; + unsigned short Asvc; + unsigned short Amount; /* AdditionalData */ + unsigned char *AdditionalData; +}; + +#define CreateAc3Descriptor(descr) \ + do \ + { \ + xCreateNode (((struct Ac3Descriptor *)descr), NULL); \ + ((struct Ac3Descriptor *)descr)->Tag = DESCR_AC3; \ + } while (0) + +#define AddAc3FlagAndValue(descr, flg, val) \ + do \ + { \ + if ((flg) & AC3_TYPE_FLAG) { \ + ((struct Ac3Descriptor *)descr)->PresentFlags |= AC3_TYPE_FLAG; \ + ((struct Ac3Descriptor *)descr)->Ac3Type = (val); } \ + else if ((flg) & BS_ID_FLAG) { \ + ((struct Ac3Descriptor *)descr)->PresentFlags |= BS_ID_FLAG; \ + ((struct Ac3Descriptor *)descr)->BsId = (val); } \ + else if ((flg) & MAIN_ID_FLAG) { \ + ((struct Ac3Descriptor *)descr)->PresentFlags |= MAIN_ID_FLAG; \ + ((struct Ac3Descriptor *)descr)->MainId = (val); } \ + else if ((flg) & ASVC_FLAG) { \ + ((struct Ac3Descriptor *)descr)->PresentFlags |= ASVC_FLAG; \ + ((struct Ac3Descriptor *)descr)->Asvc = (val); } \ + } while (0) + +#define AddAc3AdditionalData(descr, ptr, len) \ + do \ + { \ + xMemAlloc ((len)+1, &(((struct Ac3Descriptor *) \ + descr)->AdditionalData)); \ + memcpy ((((struct Ac3Descriptor *)descr)->AdditionalData),(ptr),(len)); \ + } while (0) + + /* AncillaryDataDescriptor */ struct AncillaryDataDescriptor { @@ -778,6 +832,106 @@ struct ShortEventDescriptor { } while (0) +/* TeletextDescriptor */ + +struct TeletextDescriptor { + struct NODE Node; + unsigned short Tag; + struct LIST *Items; +}; + +#define CreateTeletextDescriptor(descr) \ + do \ + { \ + xCreateNode (((struct TeletextDescriptor *)descr), NULL); \ + ((struct TeletextDescriptor *)descr)->Tag = DESCR_TELETEXT; \ + ((struct TeletextDescriptor *)descr)->Items = xNewList (NULL); \ + } while (0) + +#define TELETEXT_TYPE_INITIAL_PAGE 0x0001 +#define TELETEXT_TYPE_SUBTITLE_PAGE 0x0002 +#define TELETEXT_TYPE_ADDITIONAL_INFO 0x0003 +#define TELETEXT_TYPE_PROGRAM_SCHEDULE 0x0004 +#define TELETEXT_TYPE_HEARING_IMPAIRED 0x0005 + +struct TeletextItem { + struct NODE Node; + char LanguageCode[4]; + unsigned short Type; + unsigned short MagazineNumber; + unsigned short PageNumber; +}; + +#define CreateTeletextItem(itm, tp, mg, pg, lc1, lc2, lc3) \ + do \ + { \ + xCreateNode (itm, NULL); \ + ((struct TeletextItem *)itm)->Type = (tp); \ + ((struct TeletextItem *)itm)->MagazineNumber = (mg); \ + ((struct TeletextItem *)itm)->PageNumber = (mg); \ + ((struct TeletextItem *)itm)->LanguageCode[0] = (lc1); \ + ((struct TeletextItem *)itm)->LanguageCode[1] = (lc2); \ + ((struct TeletextItem *)itm)->LanguageCode[2] = (lc3); \ + ((struct TeletextItem *)itm)->LanguageCode[3] = '\0'; \ + } while (0) + +#define AddTeletextItem(desc, tp, mg, pg, lc1, lc2, lc3) \ + do \ + { \ + struct TeletextItem *item; \ + \ + CreateTeletextItem(item, tp, mg, pg, lc1, lc2, lc3); \ + xAddTail (((struct TeletextDescriptor *)desc)->Items, item); \ + } while (0) + + +/* SubtitlingDescriptor */ + +struct SubtitlingDescriptor { + struct NODE Node; + unsigned short Tag; + struct LIST *Items; +}; + +#define CreateSubtitlingDescriptor(descr) \ + do \ + { \ + xCreateNode (((struct SubtitlingDescriptor *)descr), NULL); \ + ((struct SubtitlingDescriptor *)descr)->Tag = DESCR_SUBTITLING; \ + ((struct SubtitlingDescriptor *)descr)->Items = xNewList (NULL); \ + } while (0) + +struct SubtitlingItem { + struct NODE Node; + char LanguageCode[4]; + unsigned char Type; + unsigned short CompositionPageId; + unsigned short AncillaryPageId; +}; + +#define CreateSubtitlingItem(itm, tp, cp, ap, lc1, lc2, lc3) \ + do \ + { \ + xCreateNode (itm, NULL); \ + ((struct SubtitlingItem *)itm)->Type = (tp); \ + ((struct SubtitlingItem *)itm)->CompositionPageId = (cp); \ + ((struct SubtitlingItem *)itm)->AncillaryPageId = (ap); \ + ((struct SubtitlingItem *)itm)->LanguageCode[0] = (lc1); \ + ((struct SubtitlingItem *)itm)->LanguageCode[1] = (lc2); \ + ((struct SubtitlingItem *)itm)->LanguageCode[2] = (lc3); \ + ((struct SubtitlingItem *)itm)->LanguageCode[3] = '\0'; \ + } while (0) + +#define AddSubtitlingItem(desc, tp, cp, ap, lc1, lc2, lc3) \ + do \ + { \ + struct SubtitlingItem *item; \ + \ + CreateSubtitlingItem(item, tp, cp, ap, lc1, lc2, lc3); \ + xAddTail (((struct SubtitlingDescriptor *)desc)->Items, item); \ + } while (0) + + /* Prototypes */ diff --git a/libdtv/libsi/include/si_tables.h b/libdtv/libsi/include/si_tables.h index 517838a..dfda3bf 100644 --- a/libdtv/libsi/include/si_tables.h +++ b/libdtv/libsi/include/si_tables.h @@ -5,9 +5,9 @@ /// /// ////////////////////////////////////////////////////////////// -// $Revision: 1.1 $ -// $Date: 2001/06/25 12:41:20 $ -// $Author: kls $ +// $Revision: 1.3 $ +// $Date: 2001/10/07 10:24:46 $ +// $Author: hakenes $ // // (C) 2001 Rolf Hakenes <hakenes@hippomi.de>, under the GNU GPL. // @@ -26,9 +26,6 @@ // Free Software Foundation, Inc., 59 Temple Place - Suite 330, // Boston, MA 02111-1307, USA. -#ifndef SI_TABLES_H -#define SI_TABLES_H - #define HILO(x) (x##_hi << 8 | x##_lo) #define MjdToEpochTime(x) (((x##_hi << 8 | x##_lo)-40587)*86400) @@ -930,14 +927,29 @@ typedef struct parental_rating_struct { /* 0x56 teletext_descriptor */ -#define DESCR_TELETEXT_LEN XX +#define DESCR_TELETEXT_LEN 2 typedef struct descr_teletext_struct { u_char descriptor_tag :8; u_char descriptor_length :8; - /* TBD */ } descr_teletext_t; #define CastTeletextDescriptor(x) ((descr_teletext_t *)(x)) +#define ITEM_TELETEXT_LEN 5 +typedef struct item_teletext_struct { + u_char lang_code1 :8; + u_char lang_code2 :8; + u_char lang_code3 :8; +#if BYTE_ORDER == BIG_ENDIAN + u_char type :5; + u_char magazine_number :3; +#else + u_char magazine_number :3; + u_char type :5; +#endif + u_char page_number :8; +} item_teletext_t; +#define CastTeletextItem(x) ((item_teletext_t *)(x)) + /* 0x57 telephone_descriptor */ @@ -963,14 +975,26 @@ typedef struct descr_local_time_offset_struct { /* 0x59 subtitling_descriptor */ -#define DESCR_SUBTITLING_LEN XX +#define DESCR_SUBTITLING_LEN 2 typedef struct descr_subtitling_struct { u_char descriptor_tag :8; u_char descriptor_length :8; - /* TBD */ } descr_subtitling_t; #define CastSubtitlingDescriptor(x) ((descr_subtitling_t *)(x)) +#define ITEM_SUBTITLING_LEN 8 +typedef struct item_subtitling_struct { + u_char lang_code1 :8; + u_char lang_code2 :8; + u_char lang_code3 :8; + u_char subtitling_type :8; + u_char composition_page_id_hi :8; + u_char composition_page_id_lo :8; + u_char ancillary_page_id_hi :8; + u_char ancillary_page_id_lo :8; +} item_subtitling_t; +#define CastSubtitlingItem(x) ((item_subtitling_t *)(x)) + /* 0x5A terrestrial_delivery_system_descriptor */ @@ -1150,11 +1174,27 @@ typedef struct descr_pdc_struct { /* 0x6A ac3_descriptor */ -#define DESCR_AC3_LEN XX +#define DESCR_AC3_LEN 3 typedef struct descr_ac3_struct { u_char descriptor_tag :8; u_char descriptor_length :8; - /* TBD */ +#if BYTE_ORDER == BIG_ENDIAN + u_char ac3_type_flag :1; + u_char bsid_flag :1; + u_char mainid_flag :1; + u_char asvc_flag :1; + u_char reserved :4; +#else + u_char reserved :4; + u_char asvc_flag :1; + u_char mainid_flag :1; + u_char bsid_flag :1; + u_char ac3_type_flag :1; +#endif + u_char ac3_type :8; + u_char bsid :8; + u_char mainid :8; + u_char asvc :8; } descr_ac3_t; #define CastAc3Descriptor(x) ((descr_ac3_t *)(x)) @@ -1202,4 +1242,4 @@ typedef struct descr_announcement_support_struct { } descr_announcement_support_t; #define CastAnnouncementSupportDescriptor(x) ((descr_announcement_support_t *)(x)) -#endif + diff --git a/libdtv/libsi/si_debug_services.c b/libdtv/libsi/si_debug_services.c index dd09cff..ae2a92a 100644 --- a/libdtv/libsi/si_debug_services.c +++ b/libdtv/libsi/si_debug_services.c @@ -4,9 +4,9 @@ /// /// ////////////////////////////////////////////////////////////// -// $Revision: 1.1 $ -// $Date: 2001/08/15 14:40:55 $ -// $Author: kls $ +// $Revision: 1.4 $ +// $Date: 2001/10/07 10:24:46 $ +// $Author: hakenes $ // // (C) 2001 Rolf Hakenes <hakenes@hippomi.de>, under the GNU GPL. // @@ -34,8 +34,6 @@ #include "si_debug_services.h" - - void siDebugServices (struct LIST *Services) { struct Service *Service; @@ -328,9 +326,9 @@ void siDebugDescriptors (char *Prepend, struct LIST *Descriptors) ((struct ExtendedEventDescriptor *)Descriptor)->LanguageCode); xForeach (((struct ExtendedEventDescriptor *)Descriptor)->Items, Item) { - printf ("%s Item:\n"); - printf ("%s Description: %s\n", xName(Item)); - printf ("%s Text: %s\n", Item->Text); + printf ("%s Item:\n", Prepend); + printf ("%s Description: %s\n", Prepend, xName(Item)); + printf ("%s Text: %s\n", Prepend, Item->Text); } } break; @@ -445,6 +443,52 @@ void siDebugDescriptors (char *Prepend, struct LIST *Descriptors) } break; + case DESCR_TELETEXT: + { + struct TeletextItem *Item; + + printf ("%sDescriptor: Teletext\n", Prepend); + xForeach (((struct TeletextDescriptor *)Descriptor)->Items, Item) + { + printf ("%s Item:\n"); + printf ("%s LanguageCode: %s\n", Prepend, Item->LanguageCode); + printf ("%s Type: ", Prepend); + switch (Item->Type) + { + case 0x01: printf ("initial Teletext page\n"); break; + case 0x02: printf ("Teletext subtitle page\n"); break; + case 0x03: printf ("additional information page\n"); break; + case 0x04: printf ("programme schedule page\n"); break; + case 0x05: printf ("Teletext subtitle page "); + printf ("for hearing impaired people\n"); break; + default: printf ("reserved for future use\n"); break; + } + printf ("%s MagazineNumber: %x\n", Prepend, Item->MagazineNumber); + printf ("%s PageNumber: %x\n", Prepend, Item->PageNumber); + } + } + break; + + case DESCR_SUBTITLING: + { + struct SubtitlingItem *Item; + + printf ("%sDescriptor: Subtitling\n", Prepend); + xForeach (((struct SubtitlingDescriptor *)Descriptor)->Items, Item) + { + printf ("%s Item:\n"); + printf ("%s LanguageCode: %s\n", Prepend, Item->LanguageCode); + printf ("%s Type: ", Prepend); + for (i = 0; i < COMPONENT_TYPE_NUMBER; i++) + if ((0x03 == ComponentTypes[i].Content) && + (Item->Type == ComponentTypes[i].Type)) + { printf ("%s\n", ComponentTypes[i].Description); break; } + printf ("%s CompositionPageId: %x\n", Prepend, Item->CompositionPageId); + printf ("%s AncillaryPageId: %x\n", Prepend, Item->AncillaryPageId); + } + } + break; + case DESCR_NW_NAME: case DESCR_SERVICE_LIST: case DESCR_STUFFING: @@ -453,10 +497,8 @@ void siDebugDescriptors (char *Prepend, struct LIST *Descriptors) case DESCR_VBI_DATA: case DESCR_VBI_TELETEXT: case DESCR_MOSAIC: - case DESCR_TELETEXT: case DESCR_TELEPHONE: case DESCR_LOCAL_TIME_OFF: - case DESCR_SUBTITLING: case DESCR_TERR_DEL_SYS: case DESCR_ML_NW_NAME: case DESCR_ML_BQ_NAME: diff --git a/libdtv/libsi/si_debug_services.h b/libdtv/libsi/si_debug_services.h index 33528db..cd4f196 100644 --- a/libdtv/libsi/si_debug_services.h +++ b/libdtv/libsi/si_debug_services.h @@ -6,7 +6,7 @@ // $Revision: 1.1 $ // $Date: 2001/06/25 12:29:47 $ -// $Author: kls $ +// $Author: hakenes $ // // (C) 2001 Rolf Hakenes <hakenes@hippomi.de>, under the GNU GPL. // diff --git a/libdtv/libsi/si_parser.c b/libdtv/libsi/si_parser.c index acafa7b..76d72c8 100644 --- a/libdtv/libsi/si_parser.c +++ b/libdtv/libsi/si_parser.c @@ -4,9 +4,9 @@ /// /// ////////////////////////////////////////////////////////////// -// $Revision: 1.1 $ -// $Date: 2001/08/15 14:41:45 $ -// $Author: kls $ +// $Revision: 1.4 $ +// $Date: 2001/10/07 10:24:46 $ +// $Author: hakenes $ // // (C) 2001 Rolf Hakenes <hakenes@hippomi.de>, under the GNU GPL. // @@ -725,6 +725,62 @@ void siParseDescriptor (struct LIST *Descriptors, u_char *Buffer) Ptr + DESCR_LINKAGE_LEN); break; + case DESCR_TELETEXT: + CreateTeletextDescriptor (Descriptor); + Length = GetDescriptorLength (Buffer) - DESCR_TELETEXT_LEN; + Ptr += DESCR_TELETEXT_LEN; + while (Length > 0) + { + AddTeletextItem (Descriptor, + CastTeletextItem(Ptr)->type, + CastTeletextItem(Ptr)->magazine_number, + CastTeletextItem(Ptr)->page_number, + CastTeletextItem(Ptr)->lang_code1, + CastTeletextItem(Ptr)->lang_code2, + CastTeletextItem(Ptr)->lang_code3); + Length -= ITEM_TELETEXT_LEN; + Ptr += ITEM_TELETEXT_LEN; + } + break; + + case DESCR_AC3: + CreateAc3Descriptor (Descriptor); + Length = GetDescriptorLength (Buffer); + if (CastAc3Descriptor(Buffer)->ac3_type_flag) + { Length -= 1; Ptr += 1; AddAc3FlagAndValue (Descriptor, + AC3_TYPE_FLAG, CastAc3Descriptor(Buffer)->ac3_type); } + if (CastAc3Descriptor(Buffer)->bsid_flag) + { Length -= 1; Ptr += 1; AddAc3FlagAndValue (Descriptor, + BS_ID_FLAG, CastAc3Descriptor(Buffer)->bsid); } + if (CastAc3Descriptor(Buffer)->mainid_flag) + { Length -= 1; Ptr += 1; AddAc3FlagAndValue (Descriptor, + MAIN_ID_FLAG, CastAc3Descriptor(Buffer)->mainid); } + if (CastAc3Descriptor(Buffer)->asvc_flag) + { Length -= 1; Ptr += 1; AddAc3FlagAndValue (Descriptor, + ASVC_FLAG, CastAc3Descriptor(Buffer)->asvc); } + Length -= DESCR_AC3_LEN; + Ptr += DESCR_AC3_LEN; + if (Length) AddAc3AdditionalData (Descriptor, Ptr, Length); + break; + + case DESCR_SUBTITLING: + CreateSubtitlingDescriptor (Descriptor); + Length = GetDescriptorLength (Buffer) - DESCR_SUBTITLING_LEN; + Ptr += DESCR_SUBTITLING_LEN; + while (Length > 0) + { + AddSubtitlingItem (Descriptor, + CastSubtitlingItem(Ptr)->subtitling_type, + HILO (CastSubtitlingItem(Ptr)->composition_page_id), + HILO (CastSubtitlingItem(Ptr)->ancillary_page_id), + CastSubtitlingItem(Ptr)->lang_code1, + CastSubtitlingItem(Ptr)->lang_code2, + CastSubtitlingItem(Ptr)->lang_code3); + Length -= ITEM_SUBTITLING_LEN; + Ptr += ITEM_SUBTITLING_LEN; + } + break; + case DESCR_VIDEO_STREAM: case DESCR_AUDIO_STREAM: case DESCR_HIERARCHY: @@ -748,10 +804,8 @@ void siParseDescriptor (struct LIST *Descriptors, u_char *Buffer) case DESCR_VBI_DATA: case DESCR_VBI_TELETEXT: case DESCR_MOSAIC: - case DESCR_TELETEXT: case DESCR_TELEPHONE: case DESCR_LOCAL_TIME_OFF: - case DESCR_SUBTITLING: case DESCR_TERR_DEL_SYS: case DESCR_ML_NW_NAME: case DESCR_ML_BQ_NAME: @@ -768,7 +822,6 @@ void siParseDescriptor (struct LIST *Descriptors, u_char *Buffer) case DESCR_TRANSPORT_STREAM: case DESCR_DSNG: case DESCR_PDC: - case DESCR_AC3: case DESCR_CELL_LIST: case DESCR_CELL_FREQ_LINK: case DESCR_ANNOUNCEMENT_SUPPORT: @@ -799,8 +852,11 @@ char *siGetDescriptorText (u_char *Buffer, u_int Length) if (*Buffer == 0) break; if ((*Buffer >= ' ' && *Buffer <= '~') || - (*Buffer >= 0xa0 && *Buffer <= 0xff)) *tmp++ = *Buffer++; - else Buffer++; + (*Buffer == '\n') || + (*Buffer >= 0xa0 && *Buffer <= 0xff)) *tmp++ = *Buffer; + if (*Buffer == 0x8A) *tmp++ = '\n'; + if (*Buffer == 0x86 || *Buffer == 0x87) *tmp++ = ' '; + Buffer++; } *tmp = '\0'; } diff --git a/libdtv/libvdr/Makefile b/libdtv/libvdr/Makefile index 8aecffc..8bcab4c 100644 --- a/libdtv/libvdr/Makefile +++ b/libdtv/libvdr/Makefile @@ -4,9 +4,9 @@ ### ### ############################################################## -## $Revision: 1.1 $ -## $Date: 2001/08/15 14:05:16 $ -## $Author: kls $ +## $Revision: 1.3 $ +## $Date: 2001/10/06 15:33:46 $ +## $Author: hakenes $ ## ## (C) 2001 Rolf Hakenes <hakenes@hippomi.de>, under the GNU GPL. ## diff --git a/libdtv/libvdr/libvdr.c b/libdtv/libvdr/libvdr.c index 5caa5d7..0ade4d3 100644 --- a/libdtv/libvdr/libvdr.c +++ b/libdtv/libvdr/libvdr.c @@ -5,8 +5,8 @@ ////////////////////////////////////////////////////////////// // $Revision: 1.1 $ -// $Date: 2001/08/15 14:05:24 $ -// $Author: kls $ +// $Date: 2001/10/07 10:25:33 $ +// $Author: hakenes $ // // (C) 2001 Rolf Hakenes <hakenes@hippomi.de>, under the GNU GPL. // diff --git a/libdtv/libvdr/libvdr.h b/libdtv/libvdr/libvdr.h index 6fde10b..421b2e7 100644 --- a/libdtv/libvdr/libvdr.h +++ b/libdtv/libvdr/libvdr.h @@ -4,9 +4,9 @@ /// /// ////////////////////////////////////////////////////////////// -// $Revision: 1.1 $ -// $Date: 2001/08/15 10:54:13 $ -// $Author: kls $ +// $Revision: 1.4 $ +// $Date: 2001/10/06 15:33:46 $ +// $Author: hakenes $ // // (C) 1992-2001 Rolf Hakenes <hakenes@hippomi.de>, under the GNU GPL. // @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: menu.c 1.127 2001/09/23 10:58:48 kls Exp $ + * $Id: menu.c 1.131 2001/10/21 14:28:14 kls Exp $ */ #include "menu.h" @@ -1636,11 +1636,12 @@ cMenuDVD::cMenuDVD(void) dvd->Open(); ifo_handle_t *vmg = dvd->openVMG(); if (vmg) { + int lastTitleID = cReplayControl::LastTitleID(); dsyslog(LOG_INFO, "DVD: vmg: %p", vmg);//XXX tt_srpt_t *tt_srpt = vmg->tt_srpt; dsyslog(LOG_INFO, "DVD: tt_srpt: %p", tt_srpt);//XXX for (int i = 0; i < tt_srpt->nr_of_srpts; i++) - Add(new cMenuDVDItem(i, tt_srpt->title[i].nr_of_ptts)); + Add(new cMenuDVDItem(i, tt_srpt->title[i].nr_of_ptts), i == lastTitleID); } } SetHelp(tr("Play"), NULL, NULL, NULL); @@ -1724,6 +1725,7 @@ void cMenuSetup::Set(void) Add(new cMenuEditIntItem( tr("OSDheight"), &data.OSDheight, MINOSDHEIGHT, MAXOSDHEIGHT)); Add(new cMenuEditIntItem( tr("OSDMessageTime"), &data.OSDMessageTime, 1, 60)); Add(new cMenuEditIntItem( tr("MaxVideoFileSize"), &data.MaxVideoFileSize, MINVIDEOFILESIZE, MAXVIDEOFILESIZE)); + Add(new cMenuEditBoolItem(tr("SplitEditedFiles"), &data.SplitEditedFiles)); Add(new cMenuEditIntItem( tr("MinEventTimeout"), &data.MinEventTimeout)); Add(new cMenuEditIntItem( tr("MinUserInactivity"), &data.MinUserInactivity)); Add(new cMenuEditBoolItem(tr("MultiSpeedMode"), &data.MultiSpeedMode)); @@ -1807,7 +1809,7 @@ eOSState cMenuCommands::ProcessKey(eKeys Key) #define STOP_RECORDING tr(" Stop recording ") -cMenuMain::cMenuMain(bool Replaying) +cMenuMain::cMenuMain(bool Replaying, eOSState State) :cOsdMenu(tr("Main")) { digit = 0; @@ -1843,6 +1845,13 @@ cMenuMain::cMenuMain(bool Replaying) Display(); lastActivity = time(NULL); SetHasHotkeys(); + switch (State) { + case osRecordings: AddSubMenu(new cMenuRecordings); break; +#ifdef DVDSUPPORT + case osDVD: AddSubMenu(new cMenuDVD); break; +#endif //DVDSUPPORT + default: break; + } } const char *cMenuMain::hk(const char *s) @@ -2374,6 +2383,11 @@ void cReplayControl::SetDVD(cDVD *DVD, int Title)//XXX dvd = DVD; titleid = Title; } + +int cReplayControl::LastTitleID(void) +{ + return titleid; +} #endif //DVDSUPPORT const char *cReplayControl::LastReplayed(void) @@ -2710,9 +2724,9 @@ eOSState cReplayControl::ProcessKey(eKeys Key) case kRight: dvbApi->Forward(); break; case kRed: TimeSearch(); break; case kGreen|k_Repeat: - case kGreen: dvbApi->SkipSeconds(-60); DoShowMode = false; break; + case kGreen: dvbApi->SkipSeconds(-60); break; case kYellow|k_Repeat: - case kYellow: dvbApi->SkipSeconds( 60); DoShowMode = false; break; + case kYellow: dvbApi->SkipSeconds( 60); break; case kBlue: Hide(); dvbApi->StopReplay(); return osEnd; @@ -2740,7 +2754,7 @@ eOSState cReplayControl::ProcessKey(eKeys Key) else Show(); break; - case kBack: return osRecordings; + case kBack: return fileName ? osRecordings : osDVD; default: return osUnknown; } } @@ -4,14 +4,12 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: menu.h 1.30 2001/09/23 10:57:33 kls Exp $ + * $Id: menu.h 1.33 2001/10/21 14:26:01 kls Exp $ */ #ifndef _MENU_H #define _MENU_H -#define _GNU_SOURCE - #include "dvbapi.h" #ifdef DVDSUPPORT #include "dvd.h" @@ -25,7 +23,7 @@ private: int digit; const char *hk(const char *s); public: - cMenuMain(bool Replaying); + cMenuMain(bool Replaying, eOSState State = osUnknown); virtual eOSState ProcessKey(eKeys Key); }; @@ -135,6 +133,7 @@ public: static void SetRecording(const char *FileName, const char *Title); #ifdef DVDSUPPORT static void SetDVD(cDVD *DVD, int Title);//XXX + static int LastTitleID(void); #endif //DVDSUPPORT static const char *LastReplayed(void); static void ClearLastReplayed(const char *FileName); diff --git a/recording.c b/recording.c index df50407..fe56a6e 100644 --- a/recording.c +++ b/recording.c @@ -4,10 +4,9 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: recording.c 1.37 2001/09/23 13:43:29 kls Exp $ + * $Id: recording.c 1.42 2001/10/20 10:28:28 kls Exp $ */ -#define _GNU_SOURCE #include "recording.h" #include <errno.h> #include <fcntl.h> @@ -32,7 +31,7 @@ #define SUMMARYFILESUFFIX "/summary.vdr" #define MARKSFILESUFFIX "/marks.vdr" -#define FINDCMD "find %s -follow -type d -name '%s' 2> /dev/null | sort -df" +#define FINDCMD "find %s -follow -type d -name '%s' 2> /dev/null" #define MINDISKSPACE 1024 // MB @@ -45,6 +44,10 @@ void RemoveDeletedRecordings(void) { static time_t LastRemoveCheck = 0; if (time(NULL) - LastRemoveCheck > REMOVECHECKDELTA) { + // Make sure only one instance of VDR does this: + cLockFile LockFile(VideoDirectory); + if (!LockFile.Lock()) + return; // Remove the oldest file that has been "deleted": cRecordings Recordings; if (Recordings.Load(true)) { @@ -74,6 +77,10 @@ void AssertFreeDiskSpace(int Priority) static time_t LastFreeDiskCheck = 0; if (time(NULL) - LastFreeDiskCheck > DISKCHECKDELTA) { if (!VideoFileSpaceAvailable(MINDISKSPACE)) { + // Make sure only one instance of VDR does this: + cLockFile LockFile(VideoDirectory); + if (!LockFile.Lock()) + return; // Remove the oldest file that has been "deleted": cRecordings Recordings; if (Recordings.Load(true)) { @@ -207,6 +214,7 @@ char *ExchangeChars(char *s, bool ToFileSystem) cRecording::cRecording(cTimer *Timer, const char *Subtitle, const char *Summary) { titleBuffer = NULL; + sortBuffer = NULL; fileName = NULL; if (Timer->IsSingleEvent() || !Setup.UseSubtitle) name = strdup(Timer->file); @@ -235,6 +243,7 @@ cRecording::cRecording(cTimer *Timer, const char *Subtitle, const char *Summary) cRecording::cRecording(const char *FileName) { titleBuffer = NULL; + sortBuffer = NULL; fileName = strdup(FileName); FileName += strlen(VideoDirectory) + 1; char *p = strrchr(FileName, '/'); @@ -243,7 +252,8 @@ cRecording::cRecording(const char *FileName) summary = NULL; if (p) { time_t now = time(NULL); - struct tm t = *localtime(&now); // this initializes the time zone in 't' + struct tm tm_r; + struct tm t = *localtime_r(&now, &tm_r); // this initializes the time zone in 't' t.tm_isdst = -1; // makes sure mktime() will determine the correct dst setting if (7 == sscanf(p + 1, DATAFORMAT, &t.tm_year, &t.tm_mon, &t.tm_mday, &t.tm_hour, &t.tm_min, &priority, &lifetime)) { t.tm_year -= 1900; @@ -294,15 +304,55 @@ cRecording::cRecording(const char *FileName) cRecording::~cRecording() { delete titleBuffer; + delete sortBuffer; delete fileName; delete name; delete summary; } +char *cRecording::StripEpisodeName(char *s) +{ + char *t = s, *s1 = NULL, *s2 = NULL; + while (*t) { + if (*t == '/') { + if (s1) { + if (s2) + s1 = s2; + s2 = t; + } + else + s1 = t; + } + t++; + } + if (s1 && s2) + memmove(s1 + 1, s2, t - s2 + 1); + return s; +} + +char *cRecording::SortName(void) +{ + if (!sortBuffer) { + char *s = StripEpisodeName(strdup(FileName() + strlen(VideoDirectory) + 1)); + int l = strxfrm(NULL, s, 0); + sortBuffer = new char[l]; + strxfrm(sortBuffer, s, l); + delete s; + } + return sortBuffer; +} + +bool cRecording::operator< (const cListObject &ListObject) +{ + cRecording *r = (cRecording *)&ListObject; + return strcasecmp(SortName(), r->SortName()) < 0; +} + const char *cRecording::FileName(void) { if (!fileName) { - struct tm *t = localtime(&start); + struct tm tm_r; + struct tm *t = localtime_r(&start, &tm_r); ExchangeChars(name, true); asprintf(&fileName, NAMEFORMAT, VideoDirectory, name, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, priority, lifetime); ExchangeChars(name, false); @@ -320,7 +370,8 @@ const char *cRecording::Title(char Delimiter, bool NewIndicator) } delete titleBuffer; titleBuffer = NULL; - struct tm *t = localtime(&start); + struct tm tm_r; + struct tm *t = localtime_r(&start, &tm_r); asprintf(&titleBuffer, "%02d.%02d%c%02d:%02d%c%c%s", t->tm_mday, t->tm_mon + 1, @@ -401,6 +452,7 @@ bool cRecordings::Load(bool Deleted) delete r; } pclose(p); + Sort(); result = Count() > 0; } else @@ -523,7 +575,7 @@ void cRecordingUserCommand::InvokeCommand(const char *State, const char *Recordi char *cmd; asprintf(&cmd, "%s %s '%s'", command, State, RecordingFileName); isyslog(LOG_INFO, "executing '%s'", cmd); - system(cmd); + SystemExec(cmd); delete cmd; } } diff --git a/recording.h b/recording.h index d2391a9..aead97e 100644 --- a/recording.h +++ b/recording.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: recording.h 1.17 2001/09/23 13:43:58 kls Exp $ + * $Id: recording.h 1.18 2001/10/07 10:38:56 kls Exp $ */ #ifndef __RECORDING_H @@ -32,9 +32,12 @@ class cRecording : public cListObject { friend class cRecordings; private: char *titleBuffer; + char *sortBuffer; char *fileName; char *name; char *summary; + char *StripEpisodeName(char *s); + char *SortName(void); public: time_t start; int priority; @@ -42,6 +45,7 @@ public: cRecording(cTimer *Timer, const char *Subtitle, const char *Summary); cRecording(const char *FileName); ~cRecording(); + virtual bool operator< (const cListObject &ListObject); const char *FileName(void); const char *Title(char Delimiter = ' ', bool NewIndicator = false); const char *Summary(void) { return summary; } @@ -6,7 +6,7 @@ * * Ported to LIRC by Carsten Koch <Carsten.Koch@icem.de> 2000-06-16. * - * $Id: remote.c 1.24 2001/08/12 15:07:26 kls Exp $ + * $Id: remote.c 1.25 2001/09/30 11:39:49 kls Exp $ */ #include "remote.h" @@ -451,6 +451,7 @@ void cRcIoLIRC::Action(void) if (Now - FirstTime < REPEATDELAY) continue; // repeat function kicks in after a short delay receivedData = receivedRepeat = true; + receivedRelease = false; } LastTime = Now; WakeUp(); @@ -10,11 +10,9 @@ * and interact with the Video Disk Recorder - or write a full featured * graphical interface that sits on top of an SVDRP connection. * - * $Id: svdrp.c 1.24 2001/09/22 13:30:02 kls Exp $ + * $Id: svdrp.c 1.25 2001/10/07 15:13:42 kls Exp $ */ -#define _GNU_SOURCE - #include "svdrp.h" #include <arpa/inet.h> #include <ctype.h> @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: thread.c 1.13 2001/09/23 14:04:35 kls Exp $ + * $Id: thread.c 1.15 2001/10/21 12:25:31 kls Exp $ */ #include "thread.h" @@ -161,7 +161,7 @@ void cThread::Cancel(int WaitSeconds) bool cThread::Lock(void) { - if (!lockingPid || lockingPid != getpid()) { + if (getpid() != lockingPid || !locked) { Mutex.Lock(); lockingPid = getpid(); } @@ -342,3 +342,35 @@ int cPipe::Close(void) return ret; } + +// --- SystemExec ------------------------------------------------------------ + +int SystemExec(const char *Command) +{ + pid_t pid; + + if ((pid = fork()) < 0) { // fork failed + LOG_ERROR; + return -1; + } + + if (pid > 0) { // parent process + int status; + if (waitpid(pid, &status, 0) < 0) { + LOG_ERROR; + return -1; + } + return status; + } + else { // child process + int MaxPossibleFileDescriptors = getdtablesize(); + for (int i = STDERR_FILENO + 1; i < MaxPossibleFileDescriptors; i++) + close(i); //close all dup'ed filedescriptors + if (execl("/bin/sh", "sh", "-c", Command, NULL) == -1) { + LOG_ERROR_STR(Command); + _exit(-1); + } + _exit(0); + } +} + @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: thread.h 1.9 2001/09/15 12:46:52 kls Exp $ + * $Id: thread.h 1.10 2001/10/20 10:25:19 kls Exp $ */ #ifndef __THREAD_H @@ -104,4 +104,9 @@ public: int Close(void); }; +// SystemExec() implements a 'system()' call that closes all unnecessary file +// descriptors in the child process. + +int SystemExec(const char *Command); + #endif //__THREAD_H @@ -4,10 +4,9 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: tools.c 1.46 2001/09/22 12:13:40 kls Exp $ + * $Id: tools.c 1.50 2001/10/19 13:12:45 kls Exp $ */ -#define _GNU_SOURCE #include "tools.h" #include <ctype.h> #include <dirent.h> @@ -74,6 +73,10 @@ char *strcpyrealloc(char *dest, const char *src) else esyslog(LOG_ERR, "ERROR: out of memory"); } + else { + delete dest; + dest = NULL; + } return dest; } @@ -413,7 +416,8 @@ const char *DayDateTime(time_t t) static char buffer[32]; if (t == 0) time(&t); - tm *tm = localtime(&t); + struct tm tm_r; + tm *tm = localtime_r(&t, &tm_r); int weekday = tm->tm_wday == 0 ? 6 : tm->tm_wday - 1; // we start with monday==0! const char *day = tr("MonTueWedThuFriSatSun"); day += weekday * 3; @@ -590,6 +594,72 @@ bool cSafeFile::Close(void) return result; } +// --- cLockFile ------------------------------------------------------------- + +#define LOCKFILENAME ".lock-vdr" +#define LOCKFILESTALETIME 600 // seconds before considering a lock file "stale" + +cLockFile::cLockFile(const char *Directory) +{ + fileName = NULL; + f = -1; + if (DirectoryOk(Directory)) + asprintf(&fileName, "%s/%s", Directory, LOCKFILENAME); +} + +cLockFile::~cLockFile() +{ + Unlock(); + delete fileName; +} + +bool cLockFile::Lock(int WaitSeconds) +{ + if (f < 0 && fileName) { + time_t Timeout = time(NULL) + WaitSeconds; + do { + f = open(fileName, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + if (f < 0) { + if (errno == EEXIST) { + struct stat fs; + if (stat(fileName, &fs) == 0) { + if (time(NULL) - fs.st_mtime > LOCKFILESTALETIME) { + esyslog(LOG_ERR, "ERROR: removing stale lock file '%s'", fileName); + if (remove(fileName) < 0) { + LOG_ERROR_STR(fileName); + break; + } + continue; + } + } + else if (errno != ENOENT) { + LOG_ERROR_STR(fileName); + break; + } + } + else { + LOG_ERROR_STR(fileName); + break; + } + if (WaitSeconds) + sleep(1); + } + } while (f < 0 && time(NULL) < Timeout); + } + return f >= 0; +} + +void cLockFile::Unlock(void) +{ + if (f >= 0) { + close(f); + remove(fileName); + f = -1; + } + else + esyslog(LOG_ERR, "ERROR: attempt to unlock %s without holding a lock!", fileName); +} + // --- cListObject ----------------------------------------------------------- cListObject::cListObject(void) @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: tools.h 1.35 2001/09/22 12:12:55 kls Exp $ + * $Id: tools.h 1.36 2001/09/30 10:20:59 kls Exp $ */ #ifndef __TOOLS_H @@ -97,6 +97,17 @@ public: bool Close(void); }; +class cLockFile { +private: + char *fileName; + int f; +public: + cLockFile(const char *Directory); + ~cLockFile(); + bool Lock(int WaitSeconds = 0); + void Unlock(void); + }; + class cListObject { private: cListObject *prev, *next; @@ -22,11 +22,11 @@ * * The project's page is at http://www.cadsoft.de/people/kls/vdr * - * $Id: vdr.c 1.79 2001/09/23 14:33:39 kls Exp $ + * $Id: vdr.c 1.86 2001/10/20 11:18:38 kls Exp $ */ -#define _GNU_SOURCE #include <getopt.h> +#include <locale.h> #include <signal.h> #include <stdlib.h> #include <unistd.h> @@ -75,6 +75,10 @@ static void Watchdog(int signum) int main(int argc, char *argv[]) { + // Initiate locale: + + setlocale(LC_ALL, ""); + // Command line options: #define DEFAULTSVDRPPORT 2001 @@ -355,7 +359,6 @@ int main(int argc, char *argv[]) cRecordControls::Process(Now); cTimer *Timer = Timers.GetMatch(Now); if (Timer) { - dsyslog(LOG_INFO, "system time seen is %s", ctime(&Now)); if (!cRecordControls::Start(Timer)) Timer->SetPending(true); } @@ -405,7 +408,7 @@ int main(int argc, char *argv[]) case osRecordings: DELETENULL(Menu); DELETENULL(ReplayControl); - Menu = new cMenuRecordings; + Menu = new cMenuMain(ReplayControl, osRecordings); break; case osReplay: DELETENULL(Menu); DELETENULL(ReplayControl); @@ -414,7 +417,7 @@ int main(int argc, char *argv[]) #ifdef DVDSUPPORT case osDVD: DELETENULL(Menu); DELETENULL(ReplayControl); - Menu = new cMenuDVD; + Menu = new cMenuMain(ReplayControl, osDVD); break; #endif //DVDSUPPORT case osStopReplay: @@ -501,10 +504,12 @@ int main(int argc, char *argv[]) if (WatchdogTimeout > 0) signal(SIGALRM, SIG_IGN); if (Interface->Confirm(tr("Press any key to cancel shutdown"), LastActivity == 1 ? 5 : SHUTDOWNWAIT, true)) { + int Channel = timer ? timer->channel : 0; + const char *File = timer ? timer->file : ""; char *cmd; - asprintf(&cmd, "%s %ld %ld", Shutdown, Next, Delta); + asprintf(&cmd, "%s %ld %ld %d '%s'", Shutdown, Next, Delta, Channel, File); isyslog(LOG_INFO, "executing '%s'", cmd); - system(cmd); + SystemExec(cmd); delete cmd; } else if (WatchdogTimeout > 0) { |