@@ -38,6 +38,9 @@ class cVideoDirectory {
38
38
bool Next (void );
39
39
void Store (void );
40
40
const char * Adjust (const char * FileName );
41
+ char * GetVidPath (int nVid );
42
+ bool GetPreferedVideoDir (void );
43
+ bool IsVidDirOK (int nVid , int * freeMB = NULL );
41
44
};
42
45
43
46
cVideoDirectory ::cVideoDirectory (void )
@@ -119,6 +122,7 @@ cUnbufferedFile *OpenVideoFile(const char *FileName, int Flags)
119
122
if ((Flags & O_CREAT ) != 0 ) {
120
123
cVideoDirectory Dir ;
121
124
if (Dir .IsDistributed ()) {
125
+ if (Setup .UseVidPrefer == 0 ) {
122
126
// Find the directory with the most free space:
123
127
int MaxFree = Dir .FreeMB ();
124
128
while (Dir .Next ()) {
@@ -128,11 +132,13 @@ cUnbufferedFile *OpenVideoFile(const char *FileName, int Flags)
128
132
MaxFree = Free ;
129
133
}
130
134
}
135
+ }
136
+ else Dir .GetPreferedVideoDir ();
131
137
if (Dir .Stored ()) {
132
138
ActualFileName = Dir .Adjust (FileName );
133
139
if (!MakeDirs (ActualFileName , false))
134
140
return NULL ; // errno has been set by MakeDirs()
135
- if (symlink (ActualFileName , FileName ) < 0 ) {
141
+ if (strcmp ( ActualFileName , FileName ) != 0 && symlink (ActualFileName , FileName ) < 0 ) {
136
142
LOG_ERROR_STR (FileName );
137
143
return NULL ;
138
144
}
@@ -381,3 +387,122 @@ void RemoveEmptyVideoDirectories(void)
381
387
} while (Dir .Next ());
382
388
}
383
389
390
+ // returns path to nVid'th video directory or NULL if not existing
391
+ char * cVideoDirectory ::GetVidPath (int nVid )
392
+ {
393
+ char * b = strdup (VideoDirectory );
394
+ int l = strlen (b ), di , n ;
395
+
396
+ while (l -- > 0 && isdigit (b [ l ]));
397
+
398
+ l ++ ;
399
+ di = strlen (b ) - l ;
400
+
401
+ // di == number of digits
402
+ n = atoi (& b [ l ]);
403
+ if (n != 0 )
404
+ return NULL ;
405
+
406
+ // add requested number to dir name
407
+ sprintf (& b [ l ], "%0*d" , di , nVid );
408
+
409
+ if (DirectoryOk (b ) == true)
410
+ return b ;
411
+
412
+ free (b );
413
+ return NULL ;
414
+ }
415
+
416
+ // checks if a video dir is 'valid'
417
+ bool cVideoDirectory ::IsVidDirOK (int nVid , int * freeMB )
418
+ {
419
+ char * dn ;
420
+ int fMB ;
421
+
422
+ if (nVid >= Setup .nVidPrefer )
423
+ return false;
424
+
425
+ if (Setup .VidPreferSize [ nVid ] == -1 )
426
+ return false;
427
+
428
+ dn = GetVidPath (nVid );
429
+ if (dn == NULL )
430
+ return false;
431
+
432
+ fMB = FreeDiskSpaceMB (dn , NULL );
433
+ if (freeMB != NULL )
434
+ * freeMB = fMB ;
435
+
436
+ free (dn );
437
+
438
+ if (Setup .VidPreferSize [ nVid ] >= fMB )
439
+ return false;
440
+ return true;
441
+ }
442
+
443
+ // calculates which video dir to use
444
+ bool cVideoDirectory ::GetPreferedVideoDir (void )
445
+ {
446
+ cVideoDirectory d ;
447
+ int nDirs = 1 ,
448
+ vidUse = Setup .nVidPrefer ;
449
+ int i , top , topFree , x ;
450
+
451
+ if (name == NULL )
452
+ return (false);
453
+
454
+ // count available video dirs
455
+ while (d .Next () == true)
456
+ nDirs ++ ;
457
+
458
+ if (vidUse > nDirs )
459
+ vidUse = nDirs ;
460
+
461
+ // check for prefered video dir
462
+ for (i = 0 , top = -1 , topFree = 0 ; i < vidUse ; i ++ ) {
463
+ if (IsVidDirOK (i , & x ) == true) {
464
+ if (top == -1 ) {
465
+ // nothing set yet, use first 'ok' dir
466
+ top = i ;
467
+ topFree = x ;
468
+ }
469
+ else {
470
+ // check if we got a higher priority
471
+ if (Setup .VidPreferPrio [ i ] >= Setup .VidPreferPrio [ top ]) {
472
+ top = i ;
473
+ topFree = x ;
474
+ }
475
+ // check if we got same priority but more space
476
+ else if (Setup .VidPreferPrio [ i ] == Setup .VidPreferPrio [ top ] && x >= topFree ) {
477
+ top = i ;
478
+ topFree = x ;
479
+ }
480
+ }
481
+ }
482
+ }
483
+
484
+ if (top == -1 ) {
485
+ isyslog ("VidPrefer: no prefered video directory could be determined!" );
486
+
487
+ // something went wrong here...
488
+ // let VDR determine the video directory
489
+ int MaxFree = FreeMB ();
490
+
491
+ while (Next ()) {
492
+ int Free = FreeDiskSpaceMB (Name ());
493
+
494
+ if (Free > MaxFree ) {
495
+ Store ();
496
+ MaxFree = Free ;
497
+ }
498
+ }
499
+ }
500
+ else {
501
+ isyslog ("VidPrefer: prefered video directory '%d' set." , top );
502
+ if (stored != NULL )
503
+ free (stored );
504
+ stored = GetVidPath (top );
505
+ }
506
+
507
+ return true;
508
+ }
0 commit comments