Changeset 9335 for trunk/libtransmission/torrent.c
- Timestamp:
- Oct 20, 2009, 3:14:44 AM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/libtransmission/torrent.c
r9333 r9335 582 582 tor->downloadDir = tr_strdup( dir ); 583 583 584 if( tr_session GetIncompleteDirEnabled( session ) )584 if( tr_sessionIsIncompleteDirEnabled( session ) ) 585 585 tor->incompleteDir = tr_strdup( tr_sessionGetIncompleteDir( session ) ); 586 586 … … 2274 2274 for( f=0; f<tor->info.fileCount; ++f ) { 2275 2275 tr_ptrArrayInsertSorted( &torrentFiles, tr_strdup( tor->info.files[f].name ), vstrcmp ); 2276 tr_ptrArrayInsertSorted( &torrentFiles, tr_ strdup_printf( "%s.part", tor->info.files[f].name), vstrcmp );2276 tr_ptrArrayInsertSorted( &torrentFiles, tr_torrentBuildPartial( tor, f ), vstrcmp ); 2277 2277 } 2278 2278 … … 2341 2341 ***/ 2342 2342 2343 static char*2344 rebaseFile( const tr_torrent * tor, tr_file_index_t fileNo,2345 const char * existingFile, const char * newRoot )2346 {2347 const char * base = strstr( existingFile, tor->info.files[fileNo].name );2348 assert( base != NULL );2349 return tr_buildPath( newRoot, base, NULL );2350 }2351 2352 2343 struct LocationData 2353 2344 { … … 2392 2383 for( i=0; !err && i<tor->info.fileCount; ++i ) 2393 2384 { 2394 struct stat sb;2395 2385 const tr_file * f = &tor->info.files[i]; 2396 char * oldpath = tr_torrentFindFile( tor, i ); 2397 char * newpath = oldpath ? rebaseFile( tor, i, oldpath, location ) : NULL; 2398 2399 if( do_move && ( oldpath != NULL ) ) 2386 const char * oldbase; 2387 char * sub; 2388 if( tr_torrentFindFile2( tor, i, &oldbase, &sub ) ) 2400 2389 { 2401 errno = 0; 2402 tr_torinf( tor, "moving \"%s\" to \"%s\"", oldpath, newpath ); 2403 if( rename( oldpath, newpath ) ) 2390 char * oldpath = tr_buildPath( oldbase, sub, NULL ); 2391 char * newpath = tr_buildPath( location, sub, NULL ); 2392 2393 if( do_move ) 2404 2394 { 2405 verify_needed = TRUE; 2406 if( tr_moveFile( oldpath, newpath ) ) 2395 errno = 0; 2396 tr_torinf( tor, "moving \"%s\" to \"%s\"", oldpath, newpath ); 2397 if( rename( oldpath, newpath ) ) 2407 2398 { 2408 err = TRUE; 2409 tr_torerr( tor, "error moving \"%s\" to \"%s\": %s", 2410 oldpath, newpath, tr_strerror( errno ) ); 2399 verify_needed = TRUE; 2400 if( tr_moveFile( oldpath, newpath ) ) 2401 { 2402 err = TRUE; 2403 tr_torerr( tor, "error moving \"%s\" to \"%s\": %s", 2404 oldpath, newpath, tr_strerror( errno ) ); 2405 } 2411 2406 } 2412 2407 } 2413 } 2414 else if( !stat( newpath, &sb ) )2415 {2416 tr_ torinf( tor, "found \"%s\"", newpath);2408 2409 tr_free( newpath ); 2410 tr_free( oldpath ); 2411 tr_free( sub ); 2417 2412 } 2418 2413 … … 2422 2417 *data->setme_progress = bytesHandled / tor->info.totalSize; 2423 2418 } 2424 2425 tr_free( newpath );2426 tr_free( oldpath );2427 2419 } 2428 2420 … … 2519 2511 tr_torrentFileCompleted( tr_torrent * tor, tr_file_index_t fileNum ) 2520 2512 { 2521 char * oldpath; 2513 char * sub; 2514 const char * base; 2522 2515 2523 2516 /* close the file so that we can reopen in read-only mode as needed */ 2524 2517 tr_fdFileClose( tor, fileNum ); 2525 2518 2526 /* if the torrent's file ends in ".part" to show that it was incomplete, 2527 * strip that suffix */ 2528 oldpath = tr_torrentFindFile( tor, fileNum ); 2529 if( oldpath != NULL ) { 2530 char * newpath = tr_strdup( oldpath ); 2531 char * pch = strrchr( newpath, '.' ); 2532 if(( pch != NULL ) && !strcmp( pch, ".part" )) { 2533 *pch = '\0'; 2519 /* if the torrent's filename on disk isn't the same as the one in the metadata, 2520 * then it's been modified to denote that it was a partial file. 2521 * Now that it's complete, use the proper filename. */ 2522 if( tr_torrentFindFile2( tor, fileNum, &base, &sub ) ) 2523 { 2524 const tr_file * file = &tor->info.files[fileNum]; 2525 2526 if( strcmp( sub, file->name ) ) 2527 { 2528 char * oldpath = tr_buildPath( base, sub, NULL ); 2529 char * newpath = tr_buildPath( base, file->name, NULL ); 2530 2534 2531 if( rename( oldpath, newpath ) ) 2535 2532 tr_torerr( tor, "Error moving \"%s\" to \"%s\": %s", oldpath, newpath, tr_strerror( errno ) ); 2533 2534 tr_free( newpath ); 2535 tr_free( oldpath ); 2536 2536 } 2537 tr_free( newpath ); 2538 }2539 tr_free( oldpath );2537 2538 tr_free( sub ); 2539 } 2540 2540 } 2541 2541 … … 2544 2544 ***/ 2545 2545 2546 enum2547 {2548 TR_FILE_PARTIAL = (1<<0),2549 TR_FILE_INCOMPLETE_DIR = (1<<1)2550 };2551 2552 static char*2553 tr_torrentBuildFilename( const tr_torrent * tor, tr_file_index_t fileNo, int flags )2554 {2555 const char * root;2556 char * base;2557 char * path;2558 const tr_bool partial = ( flags & TR_FILE_PARTIAL ) != 0;2559 const tr_bool incomplete = ( flags & TR_FILE_INCOMPLETE_DIR ) != 0;2560 2561 assert( tr_isTorrent( tor ) );2562 assert( fileNo < tor->info.fileCount );2563 2564 if( incomplete && ( tor->incompleteDir != NULL ) )2565 root = tor->incompleteDir;2566 else2567 root = tor->downloadDir;2568 2569 if( partial )2570 base = tr_strdup_printf( "%s.part", tor->info.files[fileNo].name );2571 else2572 base = tr_strdup( tor->info.files[fileNo].name );2573 2574 path = tr_buildPath( root, base, NULL );2575 2576 /* cleanup */2577 tr_free( base );2578 return path;2579 }2580 2581 2546 static tr_bool 2582 2547 fileExists( const char * filename ) … … 2587 2552 } 2588 2553 2554 tr_bool 2555 tr_torrentFindFile2( const tr_torrent * tor, tr_file_index_t fileNum, 2556 const char ** base, char ** subpath ) 2557 { 2558 char * part; 2559 const tr_file * file; 2560 const char * b = NULL; 2561 const char * s = NULL; 2562 2563 assert( tr_isTorrent( tor ) ); 2564 assert( fileNum < tor->info.fileCount ); 2565 2566 file = &tor->info.files[fileNum]; 2567 part = tr_torrentBuildPartial( tor, fileNum ); 2568 2569 if( b == NULL ) { 2570 char * filename = tr_buildPath( tor->downloadDir, part, NULL ); 2571 if( fileExists( filename ) ) { 2572 b = tor->downloadDir; 2573 s = part; 2574 } 2575 tr_free( filename ); 2576 } 2577 2578 if( b == NULL ) { 2579 char * filename = tr_buildPath( tor->downloadDir, file->name, NULL ); 2580 if( fileExists( filename ) ) { 2581 b = tor->downloadDir; 2582 s = file->name; 2583 } 2584 tr_free( filename ); 2585 } 2586 2587 if( tor->incompleteDir != NULL ) 2588 { 2589 if( b == NULL ) { 2590 char * filename = tr_buildPath( tor->incompleteDir, part, NULL ); 2591 if( fileExists( filename ) ) { 2592 b = tor->incompleteDir; 2593 s = part; 2594 } 2595 tr_free( filename ); 2596 } 2597 2598 if( b == NULL ) { 2599 char * filename = tr_buildPath( tor->incompleteDir, file->name, NULL ); 2600 if( fileExists( filename ) ) { 2601 b = tor->incompleteDir; 2602 s = file->name; 2603 } 2604 tr_free( filename ); 2605 } 2606 } 2607 2608 if( base != NULL ) 2609 *base = b; 2610 if( subpath != NULL ) 2611 *subpath = tr_strdup( s ); 2612 2613 tr_free( part ); 2614 return b != NULL; 2615 } 2616 2617 2589 2618 char* 2590 tr_torrentFindFile( const tr_torrent * tor, tr_file_index_t fileNo ) 2591 { 2592 int i; 2593 char * filename; 2594 int flags[4]; 2595 int n = 0; 2596 2597 assert( tr_isTorrent( tor ) ); 2598 assert( fileNo < tor->info.fileCount ); 2599 2600 /* based on what we know about the torrent, 2601 * put the most likely hits first... */ 2602 if( tr_cpFileIsComplete( &tor->completion, fileNo ) ) { 2603 flags[n++] = 0; 2604 flags[n++] = TR_FILE_INCOMPLETE_DIR; 2605 flags[n++] = TR_FILE_PARTIAL; 2606 flags[n++] = TR_FILE_INCOMPLETE_DIR|TR_FILE_PARTIAL; 2607 } else { 2608 flags[n++] = TR_FILE_INCOMPLETE_DIR|TR_FILE_PARTIAL; 2609 flags[n++] = TR_FILE_PARTIAL; 2610 flags[n++] = TR_FILE_INCOMPLETE_DIR; 2611 flags[n++] = 0; 2612 } 2613 2614 for( i=0; i<n; ++i ) { 2615 filename = tr_torrentBuildFilename( tor, fileNo, flags[i] ); 2616 if( fileExists( filename )) 2617 break; 2618 tr_free( filename ); 2619 filename = NULL; 2620 } 2621 2622 return filename; 2619 tr_torrentFindFile( const tr_torrent * tor, tr_file_index_t fileNum ) 2620 { 2621 char * subpath; 2622 char * ret = NULL; 2623 const char * base; 2624 2625 if( tr_torrentFindFile2( tor, fileNum, &base, &subpath ) ) 2626 { 2627 ret = tr_buildPath( base, subpath, NULL ); 2628 tr_free( subpath ); 2629 } 2630 2631 return ret; 2623 2632 } 2624 2633 … … 2627 2636 refreshCurrentDir( tr_torrent * tor ) 2628 2637 { 2629 const char * dir = tor->downloadDir; 2630 2631 if( tor->incompleteDir != NULL ) 2632 { 2633 char * tmp1 = tr_torrentBuildFilename( tor, 0, 0 ); 2634 char * tmp2 = tr_torrentBuildFilename( tor, 0, TR_FILE_PARTIAL ); 2635 2636 if( !fileExists( tmp1 ) && !fileExists( tmp2 ) ) 2637 dir = tor->incompleteDir; 2638 2639 tr_free( tmp2 ); 2640 tr_free( tmp1 ); 2641 } 2638 const char * dir = NULL; 2639 char * sub; 2640 2641 if( tor->incompleteDir == NULL ) 2642 dir = tor->downloadDir; 2643 else if( !tr_torrentFindFile2( tor, 0, &dir, &sub ) ) 2644 dir = tor->incompleteDir; 2642 2645 2643 2646 assert( dir != NULL ); … … 2645 2648 tor->currentDir = dir; 2646 2649 } 2650 2651 char* 2652 tr_torrentBuildPartial( const tr_torrent * tor, tr_file_index_t fileNum ) 2653 { 2654 return tr_strdup_printf( "%s.part", tor->info.files[fileNum].name ); 2655 }
Note: See TracChangeset
for help on using the changeset viewer.