mirror of
				https://github.com/vdr-projects/vdr.git
				synced 2025-03-01 10:50:46 +00:00 
			
		
		
		
	New command line option --dirnames
This commit is contained in:
		
							
								
								
									
										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 | ||||
|   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). | ||||
| - 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  | ||||
|   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. | ||||
| - 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, | ||||
| 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 | ||||
| the command line option '--vfat'. | ||||
| If you want to make your video directory available to other machines that | ||||
| 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 | ||||
| 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. | ||||
| - 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. | ||||
| - 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: | ||||
|  | ||||
|   | ||||
							
								
								
									
										4
									
								
								config.c
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								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 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" | ||||
| @@ -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, "MenuKeyCloses"))       MenuKeyCloses      = 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, "LnbSLOF"))             LnbSLOF            = 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 | ||||
|  * 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 | ||||
| @@ -49,7 +49,7 @@ | ||||
| #define MINOSDHEIGHT  324 | ||||
| #define MAXOSDHEIGHT 1200 | ||||
|  | ||||
| #define MaxFileName 256 | ||||
| #define MaxFileName NAME_MAX // obsolete - use NAME_MAX directly instead! | ||||
| #define MaxSkinName 16 | ||||
| #define MaxThemeName 16 | ||||
|  | ||||
| @@ -257,7 +257,7 @@ public: | ||||
|   int MenuScrollWrap; | ||||
|   int MenuKeyCloses; | ||||
|   int MarkInstantRecord; | ||||
|   char NameInstantRecord[MaxFileName]; | ||||
|   char NameInstantRecord[NAME_MAX]; | ||||
|   int InstantRecordTime; | ||||
|   int LnbSLOF; | ||||
|   int LnbFrequLo; | ||||
|   | ||||
							
								
								
									
										140
									
								
								recording.c
									
									
									
									
									
								
							
							
						
						
									
										140
									
								
								recording.c
									
									
									
									
									
								
							| @@ -4,7 +4,7 @@ | ||||
|  * See the main source file 'vdr.c' for copyright information and | ||||
|  * 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" | ||||
| @@ -64,11 +64,11 @@ | ||||
| #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 MAX_SUBTITLE_LENGTH  40 | ||||
|  | ||||
| #define MAX_LINK_LEVEL  6 | ||||
|  | ||||
| bool VfatFileSystem = false; | ||||
| int DirectoryPathMax = PATH_MAX; | ||||
| int DirectoryNameMax = NAME_MAX; | ||||
| bool DirectoryEncoding = false; | ||||
| int InstanceId = 0; | ||||
|  | ||||
| cRecordings DeletedRecordings(true); | ||||
| @@ -540,22 +540,30 @@ tCharExchange CharExchange[] = { | ||||
|   { 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 *p = s; | ||||
|   while (*p) { | ||||
|         if (VfatFileSystem) { | ||||
|            // The VFAT file system can't handle all characters, so we | ||||
|         if (DirectoryEncoding) { | ||||
|            // Some file systems can't handle all characters, so we | ||||
|            // have to take extra efforts to encode/decode them: | ||||
|            if (ToFileSystem) { | ||||
|               const char *InvalidChars = "\"\\/:*?|<>#"; | ||||
|               switch (*p) { | ||||
|                      // characters that can be mapped to other characters: | ||||
|                      case ' ': *p = '_'; break; | ||||
|                      case FOLDERDELIMCHAR: *p = '/'; break; | ||||
|                      // characters that have to be encoded: | ||||
|                      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; | ||||
|                           if (char *NewBuffer = (char *)realloc(s, strlen(s) + 10)) { | ||||
|                              s = NewBuffer; | ||||
| @@ -610,6 +618,107 @@ char *ExchangeChars(char *s, bool ToFileSystem) | ||||
|   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) | ||||
| { | ||||
|   resume = RESUME_NOT_INITIALIZED; | ||||
| @@ -628,16 +737,10 @@ cRecording::cRecording(cTimer *Timer, const cEvent *Event) | ||||
|   // set up the actual name: | ||||
|   const char *Title = Event ? Event->Title() : NULL; | ||||
|   const char *Subtitle = Event ? Event->ShortText() : NULL; | ||||
|   char SubtitleBuffer[MAX_SUBTITLE_LENGTH]; | ||||
|   if (isempty(Title)) | ||||
|      Title = Timer->Channel()->Name(); | ||||
|   if (isempty(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 *macroEPISODE = strstr(Timer->File(), TIMERMACRO_EPISODE); | ||||
|   if (macroTITLE || macroEPISODE) { | ||||
| @@ -872,9 +975,12 @@ const char *cRecording::FileName(void) const | ||||
|      const char *fmt = isPesRecording ? NAMEFORMATPES : NAMEFORMATTS; | ||||
|      int ch = isPesRecording ? priority : channel; | ||||
|      int ri = isPesRecording ? lifetime : instanceId; | ||||
|      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)); | ||||
|      name = ExchangeChars(name, false); | ||||
|      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 | ||||
|      if (strcmp(Name, name) != 0) | ||||
|         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; | ||||
| } | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
|  * See the main source file 'vdr.c' for copyright information and | ||||
|  * 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 | ||||
| @@ -22,7 +22,9 @@ | ||||
| #define TIMERMACRO_TITLE    "TITLE" | ||||
| #define TIMERMACRO_EPISODE  "EPISODE" | ||||
|  | ||||
| extern bool VfatFileSystem; | ||||
| extern int DirectoryPathMax; | ||||
| extern int DirectoryNameMax; | ||||
| extern bool DirectoryEncoding; | ||||
| extern int InstanceId; | ||||
|  | ||||
| void RemoveDeletedRecordings(void); | ||||
|   | ||||
							
								
								
									
										26
									
								
								timers.c
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								timers.c
									
									
									
									
									
								
							| @@ -4,7 +4,7 @@ | ||||
|  * See the main source file 'vdr.c' for copyright information and | ||||
|  * 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" | ||||
| @@ -17,8 +17,6 @@ | ||||
| #include "remote.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' | ||||
| // format characters in order to allow any number of blanks after a numeric | ||||
| // value! | ||||
| @@ -80,11 +78,6 @@ cTimer::cTimer(bool Instant, bool Pause, cChannel *Channel) | ||||
|   lifetime = Pause ? Setup.PauseLifetime : Setup.DefaultLifetime; | ||||
|   if (Instant && channel) | ||||
|      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) | ||||
| @@ -120,11 +113,6 @@ cTimer::cTimer(const cEvent *Event) | ||||
|   const char *Title = Event->Title(); | ||||
|   if (!isempty(Title)) | ||||
|      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); | ||||
| } | ||||
|  | ||||
| @@ -332,18 +320,6 @@ bool cTimer::Parse(const char *s) | ||||
|         } | ||||
|      //TODO add more plausibility checks | ||||
|      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)); | ||||
|      strreplace(file, '|', ':'); | ||||
|      if (isnumber(channelbuffer)) | ||||
|   | ||||
							
								
								
									
										4
									
								
								timers.h
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								timers.h
									
									
									
									
									
								
							| @@ -4,7 +4,7 @@ | ||||
|  * See the main source file 'vdr.c' for copyright information and | ||||
|  * 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 | ||||
| @@ -39,7 +39,7 @@ private: | ||||
|   int stop; | ||||
|   int priority; | ||||
|   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; | ||||
|   const cEvent *event; | ||||
| public: | ||||
|   | ||||
							
								
								
									
										14
									
								
								vdr.1
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								vdr.1
									
									
									
									
									
								
							| @@ -8,7 +8,7 @@ | ||||
| .\" License as specified in the file COPYING that comes with the | ||||
| .\" 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" | ||||
| .SH NAME | ||||
| @@ -57,6 +57,15 @@ Run in daemon mode (implies \-\-no\-kbd). | ||||
| 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). | ||||
| .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 | ||||
| Edit the given 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). | ||||
| .TP | ||||
| .BI \-\-vfat | ||||
| Encode special characters in recording names to avoid problems | ||||
| with VFAT file systems. | ||||
| For backwards compatibility (same as \-\-dirnames= 250,40,1. | ||||
| .TP | ||||
| .BI \-v\  dir ,\ \-\-video= dir | ||||
| 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 | ||||
|  * | ||||
|  * $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> | ||||
| @@ -227,6 +227,7 @@ int main(int argc, char *argv[]) | ||||
|       { "config",   required_argument, NULL, 'c' }, | ||||
|       { "daemon",   no_argument,       NULL, 'd' }, | ||||
|       { "device",   required_argument, NULL, 'D' }, | ||||
|       { "dirnames", required_argument, NULL, 'd' | 0x100 }, | ||||
|       { "edit",     required_argument, NULL, 'e' | 0x100 }, | ||||
|       { "epgfile",  required_argument, NULL, 'E' }, | ||||
|       { "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); | ||||
|                     return 2; | ||||
|                     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: | ||||
|                     return CutRecording(optarg) ? 0 : 2; | ||||
|           case 'E': EpgDataFileName = (*optarg != '-' ? optarg : NULL); | ||||
| @@ -384,7 +423,9 @@ int main(int argc, char *argv[]) | ||||
|           case 'V': DisplayVersion = true; | ||||
|                     break; | ||||
|           case 'v' | 0x100: | ||||
|                     VfatFileSystem = true; | ||||
|                     DirectoryPathMax = 250; | ||||
|                     DirectoryNameMax = 40; | ||||
|                     DirectoryEncoding = true; | ||||
|                     break; | ||||
|           case 'v': VideoDirectory = optarg; | ||||
|                     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" | ||||
|                "                           there may be several -D options (default: all DVB\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" | ||||
|                "  -E FILE,  --epgfile=FILE write the EPG data into the given FILE (default is\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" | ||||
|                "  -v DIR,   --video=DIR    use DIR as video directory (default: %s)\n" | ||||
|                "  -V,       --version      print version information and exit\n" | ||||
|                "            --vfat         encode special characters in recording names to\n" | ||||
|                "                           avoid problems with VFAT file systems\n" | ||||
|                "            --vfat         for backwards compatibility (same as\n" | ||||
|                "                           --dirnames=250,40,1\n" | ||||
|                "  -w SEC,   --watchdog=SEC activate the watchdog timer with a timeout of SEC\n" | ||||
|                "                           seconds (default: %d); '0' disables the watchdog\n" | ||||
|                "\n", | ||||
|                DEFAULTCACHEDIR, | ||||
|                DEFAULTCONFDIR, | ||||
|                PATH_MAX, | ||||
|                NAME_MAX, | ||||
|                DEFAULTEPGDATAFILENAME, | ||||
|                MAXVIDEOFILESIZEDEFAULT, | ||||
|                DEFAULTPLUGINDIR, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user