Alle domenica 4 settembre 2011, Svante Signell ha scritto: > Does this patch look OK, or is it totally wrong? Even if you change "filename" in findDirFile(), that will not be changed also in the variables passed in the various invocations of findDirFile(). Some time ago I made the attached one, but never got around polishing an sending it. Should do a bit more allocations than the code using PATH_MAX-sized arrays, but also quite less OS-specific code paths to maintain (the __GLIBC__ one is valid for basically almost all the Linux developers, so won't rot easily). -- Pino Toscano
--- a/src/dvd_reader.c +++ b/src/dvd_reader.c @@ -422,12 +422,20 @@ if( cdir >= 0 ) { chdir( path_copy ); +#ifdef __GLIBC__ + new_path = get_current_dir_name(); + if(!new_path) { + free(path); + return NULL; + } +#else new_path = malloc(PATH_MAX+1); if(!new_path) { free(path); return NULL; } getcwd(new_path, PATH_MAX ); +#endif fchdir( cdir ); close( cdir ); free( path_copy ); @@ -594,17 +602,20 @@ * or -1 on file not found. * or -2 on path not found. */ -static int findDirFile( const char *path, const char *file, char *filename ) +static int findDirFile( const char *path, const char *file, char **filename ) { DIR *dir; struct dirent *ent; + *filename = NULL; + dir = opendir( path ); if( !dir ) return -2; while( ( ent = readdir( dir ) ) != NULL ) { if( !strcasecmp( ent->d_name, file ) ) { - sprintf( filename, "%s%s%s", path, + *filename = malloc( strlen( path ) + 1 + strlen( ent->d_name ) + 1 ); + sprintf( *filename, "%s%s%s", path, ( ( path[ strlen( path ) - 1 ] == '/' ) ? "" : "/" ), ent->d_name ); closedir( dir ); @@ -616,9 +627,9 @@ return -1; } -static int findDVDFile( dvd_reader_t *dvd, const char *file, char *filename ) +static int findDVDFile( dvd_reader_t *dvd, const char *file, char **filename ) { - char video_path[ PATH_MAX + 1 ]; + char *video_path; const char *nodirfile; int ret; @@ -631,6 +642,7 @@ ret = findDirFile( dvd->path_root, nodirfile, filename ); if( ret < 0 ) { + video_path = malloc( strlen( dvd->path_root ) + 10 + 1 ); /* Try also with adding the path, just in case. */ sprintf( video_path, "%s/VIDEO_TS/", dvd->path_root ); ret = findDirFile( video_path, nodirfile, filename ); @@ -639,9 +651,11 @@ sprintf( video_path, "%s/video_ts/", dvd->path_root ); ret = findDirFile( video_path, nodirfile, filename ); if( ret < 0 ) { + free( video_path ); return 0; } } + free( video_path ); } return 1; @@ -652,13 +666,13 @@ */ static dvd_file_t *DVDOpenFilePath( dvd_reader_t *dvd, char *filename ) { - char full_path[ PATH_MAX + 1 ]; + char *full_path; dvd_file_t *dvd_file; struct stat fileinfo; dvd_input_t dev; /* Get the full path of the file. */ - if( !findDVDFile( dvd, filename, full_path ) ) { + if( !findDVDFile( dvd, filename, &full_path ) ) { fprintf( stderr, "libdvdnav:DVDOpenFilePath:findDVDFile %s failed\n", filename ); return NULL; } @@ -666,6 +680,7 @@ dev = dvdinput_open( full_path ); if( !dev ) { fprintf( stderr, "libdvdnav:DVDOpenFilePath:dvdinput_open %s failed\n", full_path ); + free( full_path ); return NULL; } @@ -673,6 +688,7 @@ if( !dvd_file ) { fprintf( stderr, "libdvdnav:DVDOpenFilePath:dvd_file malloc failed\n" ); dvdinput_close(dev); + free( full_path ); return NULL; } dvd_file->dvd = dvd; @@ -685,12 +701,15 @@ if( stat( full_path, &fileinfo ) < 0 ) { fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename ); free( dvd_file ); + free( full_path ); return NULL; } dvd_file->title_sizes[ 0 ] = fileinfo.st_size / DVD_VIDEO_LB_LEN; dvd_file->title_devs[ 0 ] = dev; dvd_file->filesize = dvd_file->title_sizes[ 0 ]; + free( full_path ); + return dvd_file; } @@ -746,7 +765,7 @@ static dvd_file_t *DVDOpenVOBPath( dvd_reader_t *dvd, int title, int menu ) { char filename[ MAX_UDF_FILE_NAME_LEN ]; - char full_path[ PATH_MAX + 1 ]; + char *full_path; struct stat fileinfo; dvd_file_t *dvd_file; int i; @@ -769,7 +788,7 @@ } else { sprintf( filename, "VTS_%02i_0.VOB", title ); } - if( !findDVDFile( dvd, filename, full_path ) ) { + if( !findDVDFile( dvd, filename, &full_path ) ) { free( dvd_file ); return NULL; } @@ -777,6 +796,7 @@ dev = dvdinput_open( full_path ); if( dev == NULL ) { free( dvd_file ); + free( full_path ); return NULL; } @@ -784,6 +804,7 @@ fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename ); dvdinput_close(dev); free( dvd_file ); + free( full_path ); return NULL; } dvd_file->title_sizes[ 0 ] = fileinfo.st_size / DVD_VIDEO_LB_LEN; @@ -791,16 +812,19 @@ dvdinput_title( dvd_file->title_devs[0], 0); dvd_file->filesize = dvd_file->title_sizes[ 0 ]; + free( full_path ); + } else { for( i = 0; i < TITLES_MAX; ++i ) { sprintf( filename, "VTS_%02i_%i.VOB", title, i + 1 ); - if( !findDVDFile( dvd, filename, full_path ) ) { + if( !findDVDFile( dvd, filename, &full_path ) ) { break; } if( stat( full_path, &fileinfo ) < 0 ) { fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename ); + free( full_path ); break; } @@ -808,6 +832,8 @@ dvd_file->title_devs[ i ] = dvdinput_open( full_path ); dvdinput_title( dvd_file->title_devs[ i ], 0 ); dvd_file->filesize += dvd_file->title_sizes[ i ]; + + free( full_path ); } if( !dvd_file->title_devs[ 0 ] ) { free( dvd_file ); @@ -938,7 +964,7 @@ int menu, dvd_stat_t *statbuf ) { char filename[ MAX_UDF_FILE_NAME_LEN ]; - char full_path[ PATH_MAX + 1 ]; + char *full_path; struct stat fileinfo; off_t tot_size; off_t parts_size[9]; @@ -952,12 +978,13 @@ } else { sprintf( filename, "VTS_%02d_%d.VOB", title, menu ? 0 : 1 ); } - if( !findDVDFile( dvd, filename, full_path ) ) { + if( !findDVDFile( dvd, filename, &full_path ) ) { return -1; } if( stat( full_path, &fileinfo ) < 0 ) { fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename ); + free( full_path ); return -1; } @@ -992,6 +1019,7 @@ for(n = 0; n < nr_parts; n++) { statbuf->parts_size[n] = parts_size[n]; } + free( full_path ); return 0; } @@ -1000,7 +1028,7 @@ dvd_read_domain_t domain, dvd_stat_t *statbuf) { char filename[ MAX_UDF_FILE_NAME_LEN ]; - char full_path[ PATH_MAX + 1 ]; + char *full_path; struct stat fileinfo; uint32_t size; @@ -1056,13 +1084,15 @@ return 0; } } else { - if( findDVDFile( dvd, filename, full_path ) ) { + if( findDVDFile( dvd, filename, &full_path ) ) { if( stat( full_path, &fileinfo ) < 0 ) { fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename ); + free( full_path ); } else { statbuf->size = fileinfo.st_size; statbuf->nr_parts = 1; statbuf->parts_size[0] = statbuf->size; + free( full_path ); return 0; } }
Attachment:
signature.asc
Description: This is a digitally signed message part.