summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTORS10
-rw-r--r--HISTORY44
-rw-r--r--INSTALL26
-rw-r--r--MANUAL11
-rw-r--r--Makefile4
-rw-r--r--channels.conf24
-rw-r--r--channels.conf.cable151
-rw-r--r--config.c37
-rw-r--r--config.h6
-rw-r--r--dvbapi.c130
-rw-r--r--eit.c35
-rw-r--r--i18n.c11
-rw-r--r--libdtv/Makefile6
-rw-r--r--libdtv/liblx/Makefile6
-rw-r--r--libdtv/liblx/liblx.h6
-rw-r--r--libdtv/liblx/xListFuncs.c2
-rw-r--r--libdtv/liblx/xMemMgt.c2
-rw-r--r--libdtv/libsi/Makefile8
-rw-r--r--libdtv/libsi/include/libsi.h178
-rw-r--r--libdtv/libsi/include/si_tables.h66
-rw-r--r--libdtv/libsi/si_debug_services.c62
-rw-r--r--libdtv/libsi/si_debug_services.h2
-rw-r--r--libdtv/libsi/si_parser.c72
-rw-r--r--libdtv/libvdr/Makefile6
-rw-r--r--libdtv/libvdr/libvdr.c4
-rw-r--r--libdtv/libvdr/libvdr.h6
-rw-r--r--menu.c26
-rw-r--r--menu.h7
-rw-r--r--recording.c66
-rw-r--r--recording.h6
-rw-r--r--remote.c3
-rw-r--r--svdrp.c4
-rw-r--r--thread.c36
-rw-r--r--thread.h7
-rw-r--r--tools.c76
-rw-r--r--tools.h13
-rw-r--r--vdr.c19
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'
diff --git a/HISTORY b/HISTORY
index 143c2f4..5087c9e 100644
--- a/HISTORY
+++ b/HISTORY
@@ -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.
diff --git a/INSTALL b/INSTALL
index b942603..e7e6731 100644
--- a/INSTALL
+++ b/INSTALL
@@ -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
diff --git a/MANUAL b/MANUAL
index 05f2f3c..7bb1ec8 100644
--- a/MANUAL
+++ b/MANUAL
@@ -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,
diff --git a/Makefile b/Makefile
index f39be08..4efae4b 100644
--- a/Makefile
+++ b/Makefile
@@ -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
diff --git a/config.c b/config.c
index 4df7361..6ebaaac 100644
--- a/config.c
+++ b/config.c
@@ -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);
diff --git a/config.h b/config.h
index 8012cd2..d0f0d77 100644
--- a/config.h
+++ b/config.h
@@ -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;
diff --git a/dvbapi.c b/dvbapi.c
index 8a6e691..786dff7 100644
--- a/dvbapi.c
+++ b/dvbapi.c
@@ -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));
}
diff --git a/eit.c b/eit.c
index 1fceeef..71ab54c 100644
--- a/eit.c
+++ b/eit.c
@@ -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;
diff --git a/i18n.c b/i18n.c
index 5e440c9..926624a 100644
--- a/i18n.c
+++ b/i18n.c
@@ -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.
//
diff --git a/menu.c b/menu.c
index 23b16e2..0242d91 100644
--- a/menu.c
+++ b/menu.c
@@ -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;
}
}
diff --git a/menu.h b/menu.h
index f7411c6..b41a935 100644
--- a/menu.h
+++ b/menu.h
@@ -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; }
diff --git a/remote.c b/remote.c
index eed9110..26d7acb 100644
--- a/remote.c
+++ b/remote.c
@@ -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();
diff --git a/svdrp.c b/svdrp.c
index 3c90bb0..43c55e4 100644
--- a/svdrp.c
+++ b/svdrp.c
@@ -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>
diff --git a/thread.c b/thread.c
index f4ba76a..b51489e 100644
--- a/thread.c
+++ b/thread.c
@@ -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);
+ }
+}
+
diff --git a/thread.h b/thread.h
index 221f9ac..89dcdf8 100644
--- a/thread.h
+++ b/thread.h
@@ -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
diff --git a/tools.c b/tools.c
index 7238137..472c50d 100644
--- a/tools.c
+++ b/tools.c
@@ -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)
diff --git a/tools.h b/tools.h
index cc67a80..843cbf1 100644
--- a/tools.h
+++ b/tools.h
@@ -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;
diff --git a/vdr.c b/vdr.c
index d7c3f06..ce86fd0 100644
--- a/vdr.c
+++ b/vdr.c
@@ -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) {