mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
New command line option --dirnames
This commit is contained in:
parent
b16437e784
commit
7f66e1573e
10
HISTORY
10
HISTORY
@ -7534,7 +7534,7 @@ Video Disk Recorder Revision History
|
|||||||
- Reduced the number of retries in cTransfer::Receive() to avoid blocking recordings
|
- Reduced the number of retries in cTransfer::Receive() to avoid blocking recordings
|
||||||
in case the primary device can't handle the current live signal.
|
in case the primary device can't handle the current live signal.
|
||||||
|
|
||||||
2013-02-03: Version 1.7.37
|
2013-02-08: Version 1.7.37
|
||||||
|
|
||||||
- Now also using FindHeader() in cMpeg2Fixer::AdjTref() (pointed out by Sören Moch).
|
- Now also using FindHeader() in cMpeg2Fixer::AdjTref() (pointed out by Sören Moch).
|
||||||
- Added missing template for DVBDIR to Make.config.template (reported by Derek Kelly).
|
- Added missing template for DVBDIR to Make.config.template (reported by Derek Kelly).
|
||||||
@ -7570,3 +7570,11 @@ Video Disk Recorder Revision History
|
|||||||
recommended that plugins that implement an interface to any kind of remote controls
|
recommended that plugins that implement an interface to any kind of remote controls
|
||||||
also use the parameters Setup.RcRepeatDelay and Setup.RcRepeatDelta for the desired
|
also use the parameters Setup.RcRepeatDelay and Setup.RcRepeatDelta for the desired
|
||||||
purpose, and remove any setup options they might have that serve the same purpose.
|
purpose, and remove any setup options they might have that serve the same purpose.
|
||||||
|
- cTimer no longer does any special "VFAT" handling to shorten directory names to 40
|
||||||
|
characters. When a string is used as a directory name for a recording, the maximum
|
||||||
|
length of the directory path, as well as the individual directory names, is now
|
||||||
|
limited to the values specified by the new command line option --dirnames (see
|
||||||
|
man vdr(1) for details). For backwards compatibility the option --vfat is still
|
||||||
|
available and has the same effect as --dirnames=250,40,1.
|
||||||
|
- The macro MaxFileName is now obsolete and may be removed in future versions. Use
|
||||||
|
NAME_MAX directly instead.
|
||||||
|
6
INSTALL
6
INSTALL
@ -58,8 +58,10 @@ Alternatively you can use the '--lirc' option at runtime.
|
|||||||
This option accepts an optional path to the remote control device,
|
This option accepts an optional path to the remote control device,
|
||||||
the default of which can be set via the LIRC_DEVICE macro.
|
the default of which can be set via the LIRC_DEVICE macro.
|
||||||
|
|
||||||
If your video directory will be on a VFAT partition, you can call VDR with
|
If you want to make your video directory available to other machines that
|
||||||
the command line option '--vfat'.
|
have limitations on directory name lengths and/or allowed characters in
|
||||||
|
directory names, you can call VDR with the command line option '--dirnames'
|
||||||
|
(see man vdr(1) for details).
|
||||||
|
|
||||||
When running, the 'vdr' program writes status information into the
|
When running, the 'vdr' program writes status information into the
|
||||||
system log file, which is usually /var/log/messages (or /var/log/user.log,
|
system log file, which is usually /var/log/messages (or /var/log/user.log,
|
||||||
|
@ -369,6 +369,12 @@ Recordings:
|
|||||||
recording, even if there is no mark set at that point.
|
recording, even if there is no mark set at that point.
|
||||||
- The new option "Setup/Replay/Pause on mark set" can be used to activate automatically
|
- The new option "Setup/Replay/Pause on mark set" can be used to activate automatically
|
||||||
going into Pause mode if an editing mark is set during replay.
|
going into Pause mode if an editing mark is set during replay.
|
||||||
|
- Timers no longer do any special "VFAT" handling to shorten directory names to 40
|
||||||
|
characters. When a string is used as a directory name for a recording, the maximum
|
||||||
|
length of the directory path, as well as the individual directory names, is now
|
||||||
|
limited to the values specified by the new command line option --dirnames (see
|
||||||
|
man vdr(1) for details). For backwards compatibility the option --vfat is still
|
||||||
|
available and has the same effect as --dirnames=250,40,1.
|
||||||
|
|
||||||
SVDRP:
|
SVDRP:
|
||||||
|
|
||||||
|
4
config.c
4
config.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: config.c 2.33 2013/02/02 13:44:33 kls Exp $
|
* $Id: config.c 2.34 2013/02/05 11:16:08 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
@ -587,7 +587,7 @@ bool cSetup::Parse(const char *Name, const char *Value)
|
|||||||
else if (!strcasecmp(Name, "MenuScrollWrap")) MenuScrollWrap = atoi(Value);
|
else if (!strcasecmp(Name, "MenuScrollWrap")) MenuScrollWrap = atoi(Value);
|
||||||
else if (!strcasecmp(Name, "MenuKeyCloses")) MenuKeyCloses = atoi(Value);
|
else if (!strcasecmp(Name, "MenuKeyCloses")) MenuKeyCloses = atoi(Value);
|
||||||
else if (!strcasecmp(Name, "MarkInstantRecord")) MarkInstantRecord = atoi(Value);
|
else if (!strcasecmp(Name, "MarkInstantRecord")) MarkInstantRecord = atoi(Value);
|
||||||
else if (!strcasecmp(Name, "NameInstantRecord")) Utf8Strn0Cpy(NameInstantRecord, Value, MaxFileName);
|
else if (!strcasecmp(Name, "NameInstantRecord")) Utf8Strn0Cpy(NameInstantRecord, Value, sizeof(NameInstantRecord));
|
||||||
else if (!strcasecmp(Name, "InstantRecordTime")) InstantRecordTime = atoi(Value);
|
else if (!strcasecmp(Name, "InstantRecordTime")) InstantRecordTime = atoi(Value);
|
||||||
else if (!strcasecmp(Name, "LnbSLOF")) LnbSLOF = atoi(Value);
|
else if (!strcasecmp(Name, "LnbSLOF")) LnbSLOF = atoi(Value);
|
||||||
else if (!strcasecmp(Name, "LnbFrequLo")) LnbFrequLo = atoi(Value);
|
else if (!strcasecmp(Name, "LnbFrequLo")) LnbFrequLo = atoi(Value);
|
||||||
|
6
config.h
6
config.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: config.h 2.63 2013/02/02 13:45:19 kls Exp $
|
* $Id: config.h 2.64 2013/02/05 11:19:20 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __CONFIG_H
|
#ifndef __CONFIG_H
|
||||||
@ -49,7 +49,7 @@
|
|||||||
#define MINOSDHEIGHT 324
|
#define MINOSDHEIGHT 324
|
||||||
#define MAXOSDHEIGHT 1200
|
#define MAXOSDHEIGHT 1200
|
||||||
|
|
||||||
#define MaxFileName 256
|
#define MaxFileName NAME_MAX // obsolete - use NAME_MAX directly instead!
|
||||||
#define MaxSkinName 16
|
#define MaxSkinName 16
|
||||||
#define MaxThemeName 16
|
#define MaxThemeName 16
|
||||||
|
|
||||||
@ -257,7 +257,7 @@ public:
|
|||||||
int MenuScrollWrap;
|
int MenuScrollWrap;
|
||||||
int MenuKeyCloses;
|
int MenuKeyCloses;
|
||||||
int MarkInstantRecord;
|
int MarkInstantRecord;
|
||||||
char NameInstantRecord[MaxFileName];
|
char NameInstantRecord[NAME_MAX];
|
||||||
int InstantRecordTime;
|
int InstantRecordTime;
|
||||||
int LnbSLOF;
|
int LnbSLOF;
|
||||||
int LnbFrequLo;
|
int LnbFrequLo;
|
||||||
|
140
recording.c
140
recording.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: recording.c 2.85 2013/01/25 14:33:16 kls Exp $
|
* $Id: recording.c 2.86 2013/02/08 09:02:07 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "recording.h"
|
#include "recording.h"
|
||||||
@ -64,11 +64,11 @@
|
|||||||
#define MARKSUPDATEDELTA 10 // seconds between checks for updating editing marks
|
#define MARKSUPDATEDELTA 10 // seconds between checks for updating editing marks
|
||||||
#define MININDEXAGE 3600 // seconds before an index file is considered no longer to be written
|
#define MININDEXAGE 3600 // seconds before an index file is considered no longer to be written
|
||||||
|
|
||||||
#define MAX_SUBTITLE_LENGTH 40
|
|
||||||
|
|
||||||
#define MAX_LINK_LEVEL 6
|
#define MAX_LINK_LEVEL 6
|
||||||
|
|
||||||
bool VfatFileSystem = false;
|
int DirectoryPathMax = PATH_MAX;
|
||||||
|
int DirectoryNameMax = NAME_MAX;
|
||||||
|
bool DirectoryEncoding = false;
|
||||||
int InstanceId = 0;
|
int InstanceId = 0;
|
||||||
|
|
||||||
cRecordings DeletedRecordings(true);
|
cRecordings DeletedRecordings(true);
|
||||||
@ -540,22 +540,30 @@ tCharExchange CharExchange[] = {
|
|||||||
{ 0, 0 }
|
{ 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const char *InvalidChars = "\"\\/:*?|<>#";
|
||||||
|
|
||||||
|
bool NeedsConversion(const char *p)
|
||||||
|
{
|
||||||
|
return DirectoryEncoding &&
|
||||||
|
(strchr(InvalidChars, *p) // characters that can't be part of a Windows file/directory name
|
||||||
|
|| *p == '.' && (!*(p + 1) || *(p + 1) == FOLDERDELIMCHAR)); // Windows can't handle '.' at the end of file/directory names
|
||||||
|
}
|
||||||
|
|
||||||
char *ExchangeChars(char *s, bool ToFileSystem)
|
char *ExchangeChars(char *s, bool ToFileSystem)
|
||||||
{
|
{
|
||||||
char *p = s;
|
char *p = s;
|
||||||
while (*p) {
|
while (*p) {
|
||||||
if (VfatFileSystem) {
|
if (DirectoryEncoding) {
|
||||||
// The VFAT file system can't handle all characters, so we
|
// Some file systems can't handle all characters, so we
|
||||||
// have to take extra efforts to encode/decode them:
|
// have to take extra efforts to encode/decode them:
|
||||||
if (ToFileSystem) {
|
if (ToFileSystem) {
|
||||||
const char *InvalidChars = "\"\\/:*?|<>#";
|
|
||||||
switch (*p) {
|
switch (*p) {
|
||||||
// characters that can be mapped to other characters:
|
// characters that can be mapped to other characters:
|
||||||
case ' ': *p = '_'; break;
|
case ' ': *p = '_'; break;
|
||||||
case FOLDERDELIMCHAR: *p = '/'; break;
|
case FOLDERDELIMCHAR: *p = '/'; break;
|
||||||
// characters that have to be encoded:
|
// characters that have to be encoded:
|
||||||
default:
|
default:
|
||||||
if (strchr(InvalidChars, *p) || *p == '.' && (!*(p + 1) || *(p + 1) == FOLDERDELIMCHAR)) { // Windows can't handle '.' at the end of file/directory names
|
if (NeedsConversion(p)) {
|
||||||
int l = p - s;
|
int l = p - s;
|
||||||
if (char *NewBuffer = (char *)realloc(s, strlen(s) + 10)) {
|
if (char *NewBuffer = (char *)realloc(s, strlen(s) + 10)) {
|
||||||
s = NewBuffer;
|
s = NewBuffer;
|
||||||
@ -610,6 +618,107 @@ char *ExchangeChars(char *s, bool ToFileSystem)
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *LimitNameLengths(char *s, int PathMax, int NameMax)
|
||||||
|
{
|
||||||
|
// Limits the total length of the directory path in 's' to PathMax, and each
|
||||||
|
// individual directory name to NameMax. The lengths of characters that need
|
||||||
|
// conversion when using 's' as a file name are taken into account accordingly.
|
||||||
|
// If a directory name exceeds NameMax, it will be truncated. If the whole
|
||||||
|
// directory path exceeds PathMax, individual directory names will be shortened
|
||||||
|
// (from right to left) until the limit is met, or until the currently handled
|
||||||
|
// directory name consists of only a single character. All operations are performed
|
||||||
|
// directly on the given 's', which may become shorter (but never longer) than
|
||||||
|
// the original value.
|
||||||
|
// Returns a pointer to 's'.
|
||||||
|
int Length = strlen(s);
|
||||||
|
int PathLength = 0;
|
||||||
|
// Collect the resulting lengths of each character:
|
||||||
|
bool NameTooLong = false;
|
||||||
|
int8_t a[Length];
|
||||||
|
int n = 0;
|
||||||
|
int NameLength = 0;
|
||||||
|
for (char *p = s; *p; p++) {
|
||||||
|
if (*p == FOLDERDELIMCHAR) {
|
||||||
|
a[n] = -1; // FOLDERDELIMCHAR is a single character, neg. sign marks it
|
||||||
|
NameTooLong |= NameLength > NameMax;
|
||||||
|
NameLength = 0;
|
||||||
|
PathLength += 1;
|
||||||
|
}
|
||||||
|
else if (NeedsConversion(p)) {
|
||||||
|
a[n] = 3; // "#xx"
|
||||||
|
NameLength += 3;
|
||||||
|
PathLength += 3;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int8_t l = Utf8CharLen(p);
|
||||||
|
a[n] = l;
|
||||||
|
NameLength += l;
|
||||||
|
PathLength += l;
|
||||||
|
while (l-- > 1) {
|
||||||
|
a[++n] = 0;
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
NameTooLong |= NameLength > NameMax;
|
||||||
|
// Limit names to NameMax:
|
||||||
|
if (NameTooLong) {
|
||||||
|
while (n > 0) {
|
||||||
|
// Calculate the length of the current name:
|
||||||
|
int NameLength = 0;
|
||||||
|
int i = n;
|
||||||
|
int b = i;
|
||||||
|
while (i-- > 0 && a[i] >= 0) {
|
||||||
|
NameLength += a[i];
|
||||||
|
b = i;
|
||||||
|
}
|
||||||
|
// Shorten the name if necessary:
|
||||||
|
if (NameLength > NameMax) {
|
||||||
|
int l = 0;
|
||||||
|
i = n;
|
||||||
|
while (i-- > 0 && a[i] >= 0) {
|
||||||
|
l += a[i];
|
||||||
|
if (NameLength - l <= NameMax) {
|
||||||
|
memmove(s + i, s + n, Length - n + 1);
|
||||||
|
memmove(a + i, a + n, Length - n + 1);
|
||||||
|
Length -= n - i;
|
||||||
|
PathLength -= l;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Switch to the next name:
|
||||||
|
n = b - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Limit path to PathMax:
|
||||||
|
n = Length;
|
||||||
|
while (PathLength > PathMax && n > 0) {
|
||||||
|
// Calculate how much to cut off the current name:
|
||||||
|
int i = n;
|
||||||
|
int b = i;
|
||||||
|
int l = 0;
|
||||||
|
while (--i > 0 && a[i - 1] >= 0) {
|
||||||
|
if (a[i] > 0) {
|
||||||
|
l += a[i];
|
||||||
|
b = i;
|
||||||
|
if (PathLength - l <= PathMax)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Shorten the name if necessary:
|
||||||
|
if (l > 0) {
|
||||||
|
memmove(s + b, s + n, Length - n + 1);
|
||||||
|
Length -= n - b;
|
||||||
|
PathLength -= l;
|
||||||
|
}
|
||||||
|
// Switch to the next name:
|
||||||
|
n = i - 1;
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
cRecording::cRecording(cTimer *Timer, const cEvent *Event)
|
cRecording::cRecording(cTimer *Timer, const cEvent *Event)
|
||||||
{
|
{
|
||||||
resume = RESUME_NOT_INITIALIZED;
|
resume = RESUME_NOT_INITIALIZED;
|
||||||
@ -628,16 +737,10 @@ cRecording::cRecording(cTimer *Timer, const cEvent *Event)
|
|||||||
// set up the actual name:
|
// set up the actual name:
|
||||||
const char *Title = Event ? Event->Title() : NULL;
|
const char *Title = Event ? Event->Title() : NULL;
|
||||||
const char *Subtitle = Event ? Event->ShortText() : NULL;
|
const char *Subtitle = Event ? Event->ShortText() : NULL;
|
||||||
char SubtitleBuffer[MAX_SUBTITLE_LENGTH];
|
|
||||||
if (isempty(Title))
|
if (isempty(Title))
|
||||||
Title = Timer->Channel()->Name();
|
Title = Timer->Channel()->Name();
|
||||||
if (isempty(Subtitle))
|
if (isempty(Subtitle))
|
||||||
Subtitle = " ";
|
Subtitle = " ";
|
||||||
else if (strlen(Subtitle) > MAX_SUBTITLE_LENGTH) {
|
|
||||||
// let's make sure the Subtitle doesn't produce too long a file name:
|
|
||||||
Utf8Strn0Cpy(SubtitleBuffer, Subtitle, MAX_SUBTITLE_LENGTH);
|
|
||||||
Subtitle = SubtitleBuffer;
|
|
||||||
}
|
|
||||||
const char *macroTITLE = strstr(Timer->File(), TIMERMACRO_TITLE);
|
const char *macroTITLE = strstr(Timer->File(), TIMERMACRO_TITLE);
|
||||||
const char *macroEPISODE = strstr(Timer->File(), TIMERMACRO_EPISODE);
|
const char *macroEPISODE = strstr(Timer->File(), TIMERMACRO_EPISODE);
|
||||||
if (macroTITLE || macroEPISODE) {
|
if (macroTITLE || macroEPISODE) {
|
||||||
@ -872,9 +975,12 @@ const char *cRecording::FileName(void) const
|
|||||||
const char *fmt = isPesRecording ? NAMEFORMATPES : NAMEFORMATTS;
|
const char *fmt = isPesRecording ? NAMEFORMATPES : NAMEFORMATTS;
|
||||||
int ch = isPesRecording ? priority : channel;
|
int ch = isPesRecording ? priority : channel;
|
||||||
int ri = isPesRecording ? lifetime : instanceId;
|
int ri = isPesRecording ? lifetime : instanceId;
|
||||||
name = ExchangeChars(name, true);
|
char *Name = LimitNameLengths(strdup(name), DirectoryPathMax - strlen(VideoDirectory) - 1 - 42, DirectoryNameMax); // 42 = length of an actual recording directory name (generated with DATAFORMATTS) plus some reserve
|
||||||
fileName = strdup(cString::sprintf(fmt, VideoDirectory, name, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, ch, ri));
|
if (strcmp(Name, name) != 0)
|
||||||
name = ExchangeChars(name, false);
|
dsyslog("recording file name '%s' truncated to '%s'", name, Name);
|
||||||
|
Name = ExchangeChars(Name, true);
|
||||||
|
fileName = strdup(cString::sprintf(fmt, VideoDirectory, Name, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, ch, ri));
|
||||||
|
free(Name);
|
||||||
}
|
}
|
||||||
return fileName;
|
return fileName;
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: recording.h 2.41 2012/12/23 15:11:53 kls Exp $
|
* $Id: recording.h 2.42 2013/02/07 13:42:17 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __RECORDING_H
|
#ifndef __RECORDING_H
|
||||||
@ -22,7 +22,9 @@
|
|||||||
#define TIMERMACRO_TITLE "TITLE"
|
#define TIMERMACRO_TITLE "TITLE"
|
||||||
#define TIMERMACRO_EPISODE "EPISODE"
|
#define TIMERMACRO_EPISODE "EPISODE"
|
||||||
|
|
||||||
extern bool VfatFileSystem;
|
extern int DirectoryPathMax;
|
||||||
|
extern int DirectoryNameMax;
|
||||||
|
extern bool DirectoryEncoding;
|
||||||
extern int InstanceId;
|
extern int InstanceId;
|
||||||
|
|
||||||
void RemoveDeletedRecordings(void);
|
void RemoveDeletedRecordings(void);
|
||||||
|
26
timers.c
26
timers.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: timers.c 2.15 2012/12/07 13:14:00 kls Exp $
|
* $Id: timers.c 2.16 2013/02/05 11:13:20 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "timers.h"
|
#include "timers.h"
|
||||||
@ -17,8 +17,6 @@
|
|||||||
#include "remote.h"
|
#include "remote.h"
|
||||||
#include "status.h"
|
#include "status.h"
|
||||||
|
|
||||||
#define VFAT_MAX_FILENAME 40 // same as MAX_SUBTITLE_LENGTH in recording.c
|
|
||||||
|
|
||||||
// IMPORTANT NOTE: in the 'sscanf()' calls there is a blank after the '%d'
|
// 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
|
// format characters in order to allow any number of blanks after a numeric
|
||||||
// value!
|
// value!
|
||||||
@ -80,11 +78,6 @@ cTimer::cTimer(bool Instant, bool Pause, cChannel *Channel)
|
|||||||
lifetime = Pause ? Setup.PauseLifetime : Setup.DefaultLifetime;
|
lifetime = Pause ? Setup.PauseLifetime : Setup.DefaultLifetime;
|
||||||
if (Instant && channel)
|
if (Instant && channel)
|
||||||
snprintf(file, sizeof(file), "%s%s", Setup.MarkInstantRecord ? "@" : "", *Setup.NameInstantRecord ? Setup.NameInstantRecord : channel->Name());
|
snprintf(file, sizeof(file), "%s%s", Setup.MarkInstantRecord ? "@" : "", *Setup.NameInstantRecord ? Setup.NameInstantRecord : channel->Name());
|
||||||
if (VfatFileSystem && (Utf8StrLen(file) > VFAT_MAX_FILENAME)) {
|
|
||||||
dsyslog("timer file name too long for VFAT file system: '%s'", file);
|
|
||||||
file[Utf8SymChars(file, VFAT_MAX_FILENAME)] = 0;
|
|
||||||
dsyslog("timer file name truncated to '%s'", file);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cTimer::cTimer(const cEvent *Event)
|
cTimer::cTimer(const cEvent *Event)
|
||||||
@ -120,11 +113,6 @@ cTimer::cTimer(const cEvent *Event)
|
|||||||
const char *Title = Event->Title();
|
const char *Title = Event->Title();
|
||||||
if (!isempty(Title))
|
if (!isempty(Title))
|
||||||
Utf8Strn0Cpy(file, Event->Title(), sizeof(file));
|
Utf8Strn0Cpy(file, Event->Title(), sizeof(file));
|
||||||
if (VfatFileSystem && (Utf8StrLen(file) > VFAT_MAX_FILENAME)) {
|
|
||||||
dsyslog("timer file name too long for VFAT file system: '%s'", file);
|
|
||||||
file[Utf8SymChars(file, VFAT_MAX_FILENAME)] = 0;
|
|
||||||
dsyslog("timer file name truncated to '%s'", file);
|
|
||||||
}
|
|
||||||
SetEvent(Event);
|
SetEvent(Event);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -332,18 +320,6 @@ bool cTimer::Parse(const char *s)
|
|||||||
}
|
}
|
||||||
//TODO add more plausibility checks
|
//TODO add more plausibility checks
|
||||||
result = ParseDay(daybuffer, day, weekdays);
|
result = ParseDay(daybuffer, day, weekdays);
|
||||||
if (VfatFileSystem) {
|
|
||||||
char *p = strrchr(filebuffer, FOLDERDELIMCHAR);
|
|
||||||
if (p)
|
|
||||||
p++;
|
|
||||||
else
|
|
||||||
p = filebuffer;
|
|
||||||
if (Utf8StrLen(p) > VFAT_MAX_FILENAME) {
|
|
||||||
dsyslog("timer file name too long for VFAT file system: '%s'", p);
|
|
||||||
p[Utf8SymChars(p, VFAT_MAX_FILENAME)] = 0;
|
|
||||||
dsyslog("timer file name truncated to '%s'", p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Utf8Strn0Cpy(file, filebuffer, sizeof(file));
|
Utf8Strn0Cpy(file, filebuffer, sizeof(file));
|
||||||
strreplace(file, '|', ':');
|
strreplace(file, '|', ':');
|
||||||
if (isnumber(channelbuffer))
|
if (isnumber(channelbuffer))
|
||||||
|
4
timers.h
4
timers.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: timers.h 2.5 2012/12/07 13:13:40 kls Exp $
|
* $Id: timers.h 2.6 2013/02/05 11:23:24 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __TIMERS_H
|
#ifndef __TIMERS_H
|
||||||
@ -39,7 +39,7 @@ private:
|
|||||||
int stop;
|
int stop;
|
||||||
int priority;
|
int priority;
|
||||||
int lifetime;
|
int lifetime;
|
||||||
mutable char file[MaxFileName];
|
mutable char file[NAME_MAX * 2]; // *2 to be able to hold 'title' and 'episode', which can each be up to 255 characters long
|
||||||
char *aux;
|
char *aux;
|
||||||
const cEvent *event;
|
const cEvent *event;
|
||||||
public:
|
public:
|
||||||
|
14
vdr.1
14
vdr.1
@ -8,7 +8,7 @@
|
|||||||
.\" License as specified in the file COPYING that comes with the
|
.\" License as specified in the file COPYING that comes with the
|
||||||
.\" vdr distribution.
|
.\" vdr distribution.
|
||||||
.\"
|
.\"
|
||||||
.\" $Id: vdr.1 2.9 2012/09/01 13:40:49 kls Exp $
|
.\" $Id: vdr.1 2.10 2013/02/07 14:40:46 kls Exp $
|
||||||
.\"
|
.\"
|
||||||
.TH vdr 1 "10 Feb 2008" "1.6" "Video Disk Recorder"
|
.TH vdr 1 "10 Feb 2008" "1.6" "Video Disk Recorder"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
@ -57,6 +57,15 @@ Run in daemon mode (implies \-\-no\-kbd).
|
|||||||
Use only the given DVB device (\fInum\fR = 0, 1, 2...).
|
Use only the given DVB device (\fInum\fR = 0, 1, 2...).
|
||||||
There may be several \fB\-D\fR options (by default all DVB devices will be used).
|
There may be several \fB\-D\fR options (by default all DVB devices will be used).
|
||||||
.TP
|
.TP
|
||||||
|
.BI \-\-dirnames= path[,name[,enc]]
|
||||||
|
Set the maximum directory path length to \fIpath\fR (default is the maximum value
|
||||||
|
allowed on the system). If \fIname\fR is also given, it defines the maximum directory
|
||||||
|
name length (default is the maximum value allowed on the system). The optional
|
||||||
|
\fIenc\fR can be 0 or 1, and controls whether special characters in directory names
|
||||||
|
are encoded as hex values (default: 0).
|
||||||
|
The length of the video directory name and that of the actual recording directory is
|
||||||
|
subtracted from \fIpath\fR, to make sure the directory path will never become too long.
|
||||||
|
.TP
|
||||||
.BI \-\-edit= rec
|
.BI \-\-edit= rec
|
||||||
Edit the given recording.
|
Edit the given recording.
|
||||||
\fIrec\fR must be the full path name of an existing recording.
|
\fIrec\fR must be the full path name of an existing recording.
|
||||||
@ -188,8 +197,7 @@ operation.
|
|||||||
allow coredumps if -u is given (only for debugging).
|
allow coredumps if -u is given (only for debugging).
|
||||||
.TP
|
.TP
|
||||||
.BI \-\-vfat
|
.BI \-\-vfat
|
||||||
Encode special characters in recording names to avoid problems
|
For backwards compatibility (same as \-\-dirnames= 250,40,1.
|
||||||
with VFAT file systems.
|
|
||||||
.TP
|
.TP
|
||||||
.BI \-v\ dir ,\ \-\-video= dir
|
.BI \-v\ dir ,\ \-\-video= dir
|
||||||
Use \fIdir\fR as video directory.
|
Use \fIdir\fR as video directory.
|
||||||
|
58
vdr.c
58
vdr.c
@ -22,7 +22,7 @@
|
|||||||
*
|
*
|
||||||
* The project's page is at http://www.tvdr.de
|
* The project's page is at http://www.tvdr.de
|
||||||
*
|
*
|
||||||
* $Id: vdr.c 2.46 2013/01/29 11:17:45 kls Exp $
|
* $Id: vdr.c 2.47 2013/02/07 13:53:01 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
@ -227,6 +227,7 @@ int main(int argc, char *argv[])
|
|||||||
{ "config", required_argument, NULL, 'c' },
|
{ "config", required_argument, NULL, 'c' },
|
||||||
{ "daemon", no_argument, NULL, 'd' },
|
{ "daemon", no_argument, NULL, 'd' },
|
||||||
{ "device", required_argument, NULL, 'D' },
|
{ "device", required_argument, NULL, 'D' },
|
||||||
|
{ "dirnames", required_argument, NULL, 'd' | 0x100 },
|
||||||
{ "edit", required_argument, NULL, 'e' | 0x100 },
|
{ "edit", required_argument, NULL, 'e' | 0x100 },
|
||||||
{ "epgfile", required_argument, NULL, 'E' },
|
{ "epgfile", required_argument, NULL, 'E' },
|
||||||
{ "filesize", required_argument, NULL, 'f' | 0x100 },
|
{ "filesize", required_argument, NULL, 'f' | 0x100 },
|
||||||
@ -277,6 +278,44 @@ int main(int argc, char *argv[])
|
|||||||
fprintf(stderr, "vdr: invalid DVB device number: %s\n", optarg);
|
fprintf(stderr, "vdr: invalid DVB device number: %s\n", optarg);
|
||||||
return 2;
|
return 2;
|
||||||
break;
|
break;
|
||||||
|
case 'd' | 0x100: {
|
||||||
|
char *s = optarg;
|
||||||
|
int n = strtol(s, &s, 10);
|
||||||
|
if (n <= 0 || n >= PATH_MAX) {
|
||||||
|
fprintf(stderr, "vdr: invalid directory path length: %s\n", optarg);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
DirectoryPathMax = n;
|
||||||
|
if (!*s)
|
||||||
|
break;
|
||||||
|
if (*s++ != ',') {
|
||||||
|
fprintf(stderr, "vdr: invalid delimiter: %s\n", optarg);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
n = strtol(s, &s, 10);
|
||||||
|
if (n <= 0 || n >= NAME_MAX) {
|
||||||
|
fprintf(stderr, "vdr: invalid directory name length: %s\n", optarg);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
DirectoryNameMax = n;
|
||||||
|
if (!*s)
|
||||||
|
break;
|
||||||
|
if (*s++ != ',') {
|
||||||
|
fprintf(stderr, "vdr: invalid delimiter: %s\n", optarg);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
n = strtol(s, &s, 10);
|
||||||
|
if (n != 0 && n != 1) {
|
||||||
|
fprintf(stderr, "vdr: invalid directory encoding: %s\n", optarg);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
DirectoryEncoding = n;
|
||||||
|
if (*s) {
|
||||||
|
fprintf(stderr, "vdr: unexpected data: %s\n", optarg);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 'e' | 0x100:
|
case 'e' | 0x100:
|
||||||
return CutRecording(optarg) ? 0 : 2;
|
return CutRecording(optarg) ? 0 : 2;
|
||||||
case 'E': EpgDataFileName = (*optarg != '-' ? optarg : NULL);
|
case 'E': EpgDataFileName = (*optarg != '-' ? optarg : NULL);
|
||||||
@ -384,7 +423,9 @@ int main(int argc, char *argv[])
|
|||||||
case 'V': DisplayVersion = true;
|
case 'V': DisplayVersion = true;
|
||||||
break;
|
break;
|
||||||
case 'v' | 0x100:
|
case 'v' | 0x100:
|
||||||
VfatFileSystem = true;
|
DirectoryPathMax = 250;
|
||||||
|
DirectoryNameMax = 40;
|
||||||
|
DirectoryEncoding = true;
|
||||||
break;
|
break;
|
||||||
case 'v': VideoDirectory = optarg;
|
case 'v': VideoDirectory = optarg;
|
||||||
while (optarg && *optarg && optarg[strlen(optarg) - 1] == '/')
|
while (optarg && *optarg && optarg[strlen(optarg) - 1] == '/')
|
||||||
@ -435,6 +476,13 @@ int main(int argc, char *argv[])
|
|||||||
" -D NUM, --device=NUM use only the given DVB device (NUM = 0, 1, 2...)\n"
|
" -D NUM, --device=NUM use only the given DVB device (NUM = 0, 1, 2...)\n"
|
||||||
" there may be several -D options (default: all DVB\n"
|
" there may be several -D options (default: all DVB\n"
|
||||||
" devices will be used)\n"
|
" devices will be used)\n"
|
||||||
|
" --dirnames=PATH[,NAME[,ENC]]\n"
|
||||||
|
" set the maximum directory path length to PATH\n"
|
||||||
|
" (default: %d); if NAME is also given, it defines\n"
|
||||||
|
" the maximum directory name length (default: %d);\n"
|
||||||
|
" the optional ENC can be 0 or 1, and controls whether\n"
|
||||||
|
" special characters in directory names are encoded as\n"
|
||||||
|
" hex values (default: 0)\n"
|
||||||
" --edit=REC cut recording REC and exit\n"
|
" --edit=REC cut recording REC and exit\n"
|
||||||
" -E FILE, --epgfile=FILE write the EPG data into the given FILE (default is\n"
|
" -E FILE, --epgfile=FILE write the EPG data into the given FILE (default is\n"
|
||||||
" '%s' in the video directory)\n"
|
" '%s' in the video directory)\n"
|
||||||
@ -477,13 +525,15 @@ int main(int argc, char *argv[])
|
|||||||
" --userdump allow coredumps if -u is given (debugging)\n"
|
" --userdump allow coredumps if -u is given (debugging)\n"
|
||||||
" -v DIR, --video=DIR use DIR as video directory (default: %s)\n"
|
" -v DIR, --video=DIR use DIR as video directory (default: %s)\n"
|
||||||
" -V, --version print version information and exit\n"
|
" -V, --version print version information and exit\n"
|
||||||
" --vfat encode special characters in recording names to\n"
|
" --vfat for backwards compatibility (same as\n"
|
||||||
" avoid problems with VFAT file systems\n"
|
" --dirnames=250,40,1\n"
|
||||||
" -w SEC, --watchdog=SEC activate the watchdog timer with a timeout of SEC\n"
|
" -w SEC, --watchdog=SEC activate the watchdog timer with a timeout of SEC\n"
|
||||||
" seconds (default: %d); '0' disables the watchdog\n"
|
" seconds (default: %d); '0' disables the watchdog\n"
|
||||||
"\n",
|
"\n",
|
||||||
DEFAULTCACHEDIR,
|
DEFAULTCACHEDIR,
|
||||||
DEFAULTCONFDIR,
|
DEFAULTCONFDIR,
|
||||||
|
PATH_MAX,
|
||||||
|
NAME_MAX,
|
||||||
DEFAULTEPGDATAFILENAME,
|
DEFAULTEPGDATAFILENAME,
|
||||||
MAXVIDEOFILESIZEDEFAULT,
|
MAXVIDEOFILESIZEDEFAULT,
|
||||||
DEFAULTPLUGINDIR,
|
DEFAULTPLUGINDIR,
|
||||||
|
Loading…
Reference in New Issue
Block a user