~ubuntu-branches/debian/sid/libdvdread/sid

« back to all changes in this revision

Viewing changes to src/dvd_reader.c

  • Committer: Package Import Robot
  • Author(s): Reinhard Tartler, Matteo F. Vescovi, Benjamin Drung, Reinhard Tartler
  • Date: 2014-08-15 22:10:40 UTC
  • mfrom: (1.3.5)
  • Revision ID: package-import@ubuntu.com-20140815221040-nzkc3dzjjeo9tgji
Tags: 5.0.0-1
[ Matteo F. Vescovi ]
* New upstream release
  - debian/patches: patchset re-worked against v4.9.9
* Imported Upstream version 4.9.9
* debian/patches: patchset re-worked against v4.9.9

[ Benjamin Drung ]
* dvdread-config is gone now.
* Drop dvdread-config_manpage.patch.
* DEVELOPMENT-POLICY.txt is gone.
* debian/rules: Update list of unused files.
* Add missing pkg-config dependency.

[ Reinhard Tartler ]
* Imported Upstream version 5.0.0
  - Fixes libdvdread runs out of memory (LP: #377414)
  - Fixes: libdvdread4 unable to read Wall.e encrypted DVDs (LP: #590983)
  - Fixes: libdvdread: Can't seek to block (LP: #983535, #446664, #1066317)
  - Fixes: Zero check failed in ifo_read.c:904 for pgc->subp_control[i]
           = 0x00000001 (LP: #1179913, Closes: #504256)
* Refresh patches, drop merged patches

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21
21
 */
22
22
 
23
 
#include <sys/types.h>
24
 
#include <sys/stat.h>
25
 
#include <sys/time.h> /* For the timing of dvdcss_title crack. */
26
 
#include <fcntl.h>
27
 
#include <stdlib.h>
28
 
#include <stdio.h>
29
 
#include <errno.h>
30
 
#include <string.h>
31
 
#include <strings.h>
32
 
#include <ctype.h>
33
 
#define _GNU_SOURCE
34
 
#define __USE_GNU
35
 
#include <unistd.h>
36
 
#include <limits.h>
37
 
#include <dirent.h>
 
23
#include "config.h"
 
24
#include <sys/types.h>      /* off_t */
 
25
#include <sys/stat.h>       /* stat */
 
26
#include <sys/time.h>       /* For the timing of dvdcss_title crack. */
 
27
#include <fcntl.h>          /* open */
 
28
#include <stdlib.h>         /* free */
 
29
#include <stdio.h>          /* fprintf */
 
30
#include <errno.h>          /* errno, EIN* */
 
31
#include <string.h>         /* memcpy, strlen */
 
32
#define _GNU_SOURCE         /* Hurd support */
 
33
#define __USE_GNU           /* Fix segfault */
 
34
#include <unistd.h>         /* chdir, getcwd */
 
35
#include <limits.h>         /* PATH_MAX */
 
36
#include <dirent.h>         /* opendir, readdir */
 
37
#include <ctype.h>          /* isalpha */
38
38
 
39
39
/* misc win32 helpers */
40
40
#ifdef WIN32
41
 
#ifndef HAVE_GETTIMEOFDAY
42
 
/* replacement gettimeofday implementation */
43
 
#include <sys/timeb.h>
 
41
# ifndef HAVE_GETTIMEOFDAY
 
42
   /* replacement gettimeofday implementation */
 
43
#  include <sys/timeb.h>
44
44
static inline int _private_gettimeofday( struct timeval *tv, void *tz )
45
45
{
46
46
  struct timeb t;
49
49
  tv->tv_usec = t.millitm * 1000;
50
50
  return 0;
51
51
}
52
 
#define gettimeofday(TV, TZ) _private_gettimeofday((TV), (TZ))
53
 
#endif
54
 
#include <io.h> /* read() */
55
 
#define lseek64 _lseeki64
 
52
#  define gettimeofday(TV, TZ) _private_gettimeofday((TV), (TZ))
 
53
# endif
 
54
# include <io.h> /* read() */
 
55
# define lseek64 _lseeki64
56
56
#endif
57
57
 
58
58
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__bsdi__) || defined(__APPLE__)
59
 
#define SYS_BSD 1
 
59
# define SYS_BSD 1
60
60
#endif
61
61
 
62
62
#if defined(__sun)
63
 
#include <sys/mnttab.h>
 
63
# include <sys/mnttab.h>
 
64
#elif defined(__APPLE__)
 
65
# include <sys/param.h>
 
66
# include <sys/ucred.h>
 
67
# include <sys/mount.h>
64
68
#elif defined(SYS_BSD)
65
 
#include <fstab.h>
 
69
# include <fstab.h>
66
70
#elif defined(__linux__)
67
 
#include <mntent.h>
68
 
#include <paths.h>
 
71
# include <mntent.h>
 
72
# include <paths.h>
69
73
#endif
70
74
 
71
75
#include "dvdread/dvd_udf.h"
 
76
#include "dvdread/dvd_reader.h"
72
77
#include "dvd_input.h"
73
 
#include "dvdread/dvd_reader.h"
 
78
#include "dvdread_internal.h"
74
79
#include "md5.h"
 
80
#include "dvdread/ifo_read.h"
75
81
 
76
82
#define DEFAULT_UDF_CACHE_LEVEL 1
77
83
 
116
122
  ssize_t filesize;
117
123
};
118
124
 
119
 
int UDFReadBlocksRaw( dvd_reader_t *device, uint32_t lb_number,
 
125
int InternalUDFReadBlocksRaw( const dvd_reader_t *device, uint32_t lb_number,
120
126
                      size_t block_count, unsigned char *data,
121
127
                      int encrypted );
122
128
 
238
244
    return NULL;
239
245
  }
240
246
 
241
 
  dvd = (dvd_reader_t *) malloc( sizeof( dvd_reader_t ) );
 
247
  dvd = malloc( sizeof( dvd_reader_t ) );
242
248
  if( !dvd ) {
243
249
    dvdinput_close(dev);
244
250
    return NULL;
245
251
  }
 
252
  memset( dvd, 0, sizeof( dvd_reader_t ) );
246
253
  dvd->isImageFile = 1;
247
254
  dvd->dev = dev;
248
255
  dvd->path_root = NULL;
266
273
{
267
274
  dvd_reader_t *dvd;
268
275
 
269
 
  dvd = (dvd_reader_t *) malloc( sizeof( dvd_reader_t ) );
 
276
  dvd = malloc( sizeof( dvd_reader_t ) );
270
277
  if( !dvd ) return NULL;
271
278
  dvd->isImageFile = 0;
272
279
  dvd->dev = 0;
273
280
  dvd->path_root = strdup( path_root );
274
281
  if(!dvd->path_root) {
275
282
    free(dvd);
276
 
    return 0;
 
283
    return NULL;
277
284
  }
278
285
  dvd->udfcache_level = DEFAULT_UDF_CACHE_LEVEL;
279
286
  dvd->udfcache = NULL;
297
304
 
298
305
  /* Replace "/dsk/" with "/rdsk/" */
299
306
  new_path = malloc( strlen(path) + 2 );
 
307
  if(!new_path) return NULL;
300
308
  strcpy( new_path, path );
301
309
  strcpy( strstr( new_path, "/dsk/" ), "" );
302
310
  strcat( new_path, "/rdsk/" );
328
336
 
329
337
  /* Replace "/dev/" with "/dev/r" */
330
338
  new_path = malloc( strlen(path) + 2 );
 
339
  if(!new_path) return NULL;
331
340
  strcpy( new_path, "/dev/r" );
332
341
  strcat( new_path, path + strlen( "/dev/" ) );
333
342
 
403
412
#else
404
413
    dev_name = strdup( path );
405
414
#endif
 
415
    if(!dev_name)
 
416
        goto DVDOpen_error;
406
417
    dvd = DVDOpenImageFile( dev_name, have_css );
407
418
    free( dev_name );
408
419
    free(path);
484
495
      path_copy[1] = '\0';
485
496
    }
486
497
 
487
 
#if defined(SYS_BSD)
 
498
#if defined(__APPLE__)
 
499
    struct statfs s[128];
 
500
    int r = getfsstat(NULL, 0, MNT_NOWAIT);
 
501
    if (r > 0) {
 
502
        if (r > 128)
 
503
            r = 128;
 
504
        r = getfsstat(s, r * sizeof(s[0]), MNT_NOWAIT);
 
505
        int i;
 
506
        for (i=0; i<r; i++) {
 
507
            if (!strcmp(path_copy, s[i].f_mntonname)) {
 
508
                dev_name = bsd_block2char(s[i].f_mntfromname);
 
509
                fprintf( stderr,
 
510
                        "libdvdread: Attempting to use device %s"
 
511
                        " mounted on %s for CSS authentication\n",
 
512
                        dev_name,
 
513
                        s[i].f_mntonname);
 
514
                auth_drive = DVDOpenImageFile( dev_name, have_css );
 
515
                break;
 
516
            }
 
517
        }
 
518
    }
 
519
#elif defined(SYS_BSD)
488
520
    if( ( fe = getfsfile( path_copy ) ) ) {
489
521
      dev_name = bsd_block2char( fe->fs_spec );
490
522
      fprintf( stderr,
611
643
 
612
644
  start = UDFFindFile( dvd, filename, &len );
613
645
  if( !start ) {
614
 
    fprintf( stderr, "libdvdnav:DVDOpenFileUDF:UDFFindFile %s failed\n", filename );
 
646
    fprintf( stderr, "libdvdread:DVDOpenFileUDF:UDFFindFile %s failed\n", filename );
615
647
    return NULL;
616
648
  }
617
649
 
618
 
  dvd_file = (dvd_file_t *) malloc( sizeof( dvd_file_t ) );
 
650
  dvd_file = malloc( sizeof( dvd_file_t ) );
619
651
  if( !dvd_file ) {
620
 
    fprintf( stderr, "libdvdnav:DVDOpenFileUDF:malloc failed\n" );
 
652
    fprintf( stderr, "libdvdread:DVDOpenFileUDF:malloc failed\n" );
621
653
    return NULL;
622
654
  }
623
655
  dvd_file->dvd = dvd;
710
742
 
711
743
  /* Get the full path of the file. */
712
744
  if( !findDVDFile( dvd, filename, &full_path ) ) {
713
 
    fprintf( stderr, "libdvdnav:DVDOpenFilePath:findDVDFile %s failed\n", filename );
 
745
    fprintf( stderr, "libdvdread:DVDOpenFilePath:findDVDFile %s failed\n", filename );
714
746
    free( full_path );
715
747
    return NULL;
716
748
  }
717
749
 
718
750
  dev = dvdinput_open( full_path );
719
751
  if( !dev ) {
720
 
    fprintf( stderr, "libdvdnav:DVDOpenFilePath:dvdinput_open %s failed\n", full_path );
 
752
    fprintf( stderr, "libdvdread:DVDOpenFilePath:dvdinput_open %s failed\n", full_path );
721
753
    free( full_path );
722
754
    return NULL;
723
755
  }
724
756
 
725
 
  dvd_file = (dvd_file_t *) malloc( sizeof( dvd_file_t ) );
 
757
  dvd_file = malloc( sizeof( dvd_file_t ) );
726
758
  if( !dvd_file ) {
727
 
    fprintf( stderr, "libdvdnav:DVDOpenFilePath:dvd_file malloc failed\n" );
 
759
    fprintf( stderr, "libdvdread:DVDOpenFilePath:dvd_file malloc failed\n" );
728
760
    dvdinput_close(dev);
729
761
    free( full_path );
730
762
    return NULL;
740
772
    fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename );
741
773
    free( full_path );
742
774
    free( dvd_file );
 
775
    dvdinput_close( dev );
743
776
    return NULL;
744
777
  }
745
778
  dvd_file->title_sizes[ 0 ] = fileinfo.st_size / DVD_VIDEO_LB_LEN;
764
797
  start = UDFFindFile( dvd, filename, &len );
765
798
  if( start == 0 ) return NULL;
766
799
 
767
 
  dvd_file = (dvd_file_t *) malloc( sizeof( dvd_file_t ) );
 
800
  dvd_file = malloc( sizeof( dvd_file_t ) );
768
801
  if( !dvd_file ) return NULL;
769
802
  dvd_file->dvd = dvd;
770
803
  /*Hack*/ dvd_file->css_title = title << 1 | menu;
807
840
  dvd_file_t *dvd_file;
808
841
  int i;
809
842
 
810
 
  dvd_file = (dvd_file_t *) malloc( sizeof( dvd_file_t ) );
 
843
  dvd_file = malloc( sizeof( dvd_file_t ) );
811
844
  if( !dvd_file ) return NULL;
812
845
  dvd_file->dvd = dvd;
813
846
  /*Hack*/ dvd_file->css_title = title << 1 | menu;
874
907
      return NULL;
875
908
    }
876
909
  }
 
910
 
877
911
  free( full_path );
878
912
  return dvd_file;
879
913
}
910
944
    }
911
945
    break;
912
946
  case DVD_READ_TITLE_VOBS:
913
 
    if( titlenum == 0 ) return 0;
 
947
    if( titlenum == 0 ) return NULL;
914
948
    if( dvd->isImageFile ) {
915
949
      return DVDOpenVOBUDF( dvd, titlenum, 0 );
916
950
    } else {
933
967
{
934
968
  int i;
935
969
 
936
 
  if( dvd_file ) {
 
970
  if( dvd_file && dvd_file->dvd ) {
937
971
    if( !dvd_file->dvd->isImageFile ) {
938
972
      for( i = 0; i < TITLES_MAX; ++i ) {
939
973
        if( dvd_file->title_devs[ i ] ) {
943
977
    }
944
978
 
945
979
    free( dvd_file );
946
 
    dvd_file = 0;
 
980
    dvd_file = NULL;
947
981
  }
948
982
}
949
983
 
1128
1162
}
1129
1163
 
1130
1164
/* Internal, but used from dvd_udf.c */
1131
 
int UDFReadBlocksRaw( dvd_reader_t *device, uint32_t lb_number,
 
1165
int InternalUDFReadBlocksRaw( const dvd_reader_t *device, uint32_t lb_number,
1132
1166
                      size_t block_count, unsigned char *data,
1133
1167
                      int encrypted )
1134
1168
{
1156
1190
 * into the buffer located at 'data' and if 'encrypted' is set
1157
1191
 * descramble the data if it's encrypted.  Returning either an
1158
1192
 * negative error or the number of blocks read. */
1159
 
static int DVDReadBlocksUDF( dvd_file_t *dvd_file, uint32_t offset,
 
1193
static int DVDReadBlocksUDF( const dvd_file_t *dvd_file, uint32_t offset,
1160
1194
                             size_t block_count, unsigned char *data,
1161
1195
                             int encrypted )
1162
1196
{
1163
 
  return UDFReadBlocksRaw( dvd_file->dvd, dvd_file->lb_start + offset,
 
1197
  return InternalUDFReadBlocksRaw( dvd_file->dvd, dvd_file->lb_start + offset,
1164
1198
                           block_count, data, encrypted );
1165
1199
}
1166
1200
 
1170
1204
 * into the buffer located at 'data' and if 'encrypted' is set
1171
1205
 * descramble the data if it's encrypted.  Returning either an
1172
1206
 * negative error or the number of blocks read. */
1173
 
static int DVDReadBlocksPath( dvd_file_t *dvd_file, unsigned int offset,
 
1207
static int DVDReadBlocksPath( const dvd_file_t *dvd_file, unsigned int offset,
1174
1208
                              size_t block_count, unsigned char *data,
1175
1209
                              int encrypted )
1176
1210
{
1322
1356
  numsec = ( ( seek_byte + byte_size ) / DVD_VIDEO_LB_LEN ) +
1323
1357
    ( ( ( seek_byte + byte_size ) % DVD_VIDEO_LB_LEN ) ? 1 : 0 );
1324
1358
 
1325
 
  secbuf_base = (unsigned char *) malloc( numsec * DVD_VIDEO_LB_LEN + 2048 );
 
1359
  secbuf_base = malloc( numsec * DVD_VIDEO_LB_LEN + 2048 );
1326
1360
  secbuf = (unsigned char *)(((uintptr_t)secbuf_base & ~((uintptr_t)2047)) + 2048);
1327
1361
  if( !secbuf_base ) {
1328
1362
    fprintf( stderr, "libdvdread: Can't allocate memory "
1363
1397
{
1364
1398
  struct md5_ctx ctx;
1365
1399
  int title;
 
1400
  int title_sets;
1366
1401
  int nr_of_files = 0;
 
1402
  ifo_handle_t *vmg_ifo;
1367
1403
 
1368
1404
  /* Check arguments. */
1369
1405
  if( dvd == NULL || discid == NULL )
1370
1406
    return 0;
1371
1407
 
1372
 
  /* Go through the first 10 IFO:s, in order,
 
1408
  vmg_ifo = ifoOpen( dvd, 0 );
 
1409
  if( !vmg_ifo ) {
 
1410
    fprintf( stderr, "libdvdread: DVDDiscId, failed to "
 
1411
      "open VMG IFO!\n" );
 
1412
    return -1;
 
1413
  }
 
1414
 
 
1415
  title_sets = vmg_ifo->vmgi_mat->vmg_nr_of_title_sets + 1;
 
1416
  ifoClose( vmg_ifo );
 
1417
 
 
1418
  if( title_sets > 10 )
 
1419
        title_sets = 10;
 
1420
 
 
1421
  /* Go through the first IFO:s, in order, up until the tenth,
1373
1422
   * and md5sum them, i.e  VIDEO_TS.IFO and VTS_0?_0.IFO */
1374
1423
  md5_init_ctx( &ctx );
1375
 
  for( title = 0; title < 10; title++ ) {
 
1424
  for( title = 0; title < title_sets; title++ ) {
1376
1425
    dvd_file_t *dvd_file = DVDOpenFile( dvd, title, DVD_READ_INFO_FILE );
1377
1426
    if( dvd_file != NULL ) {
1378
1427
      ssize_t bytes_read;
1379
 
      size_t file_size = dvd_file->filesize * DVD_VIDEO_LB_LEN;
 
1428
      ssize_t file_size = dvd_file->filesize * DVD_VIDEO_LB_LEN;
1380
1429
      char *buffer_base = malloc( file_size + 2048 );
1381
1430
      char *buffer = (char *)(((uintptr_t)buffer_base & ~((uintptr_t)2047)) + 2048);
1382
1431
 
1436
1485
    return -1;
1437
1486
  }
1438
1487
 
1439
 
  ret = UDFReadBlocksRaw( dvd, 16, 1, buffer, 0 );
 
1488
  ret = InternalUDFReadBlocksRaw( dvd, 16, 1, buffer, 0 );
1440
1489
  if( ret != 1 ) {
1441
1490
    fprintf( stderr, "libdvdread: DVDISOVolumeInfo, failed to "
1442
1491
             "read ISO9660 Primary Volume Descriptor!\n" );