Changeset 9328 for trunk/libtransmission/torrent.c
- Timestamp:
- Oct 19, 2009, 5:05:00 AM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/libtransmission/torrent.c
r9276 r9328 551 551 } 552 552 553 static void refreshCurrentDir( tr_torrent * tor );; 554 553 555 static void 554 556 torrentRealInit( tr_torrent * tor, const tr_ctor * ctor ) … … 579 581 !tr_ctorGetDownloadDir( ctor, TR_FALLBACK, &dir ) ) 580 582 tor->downloadDir = tr_strdup( dir ); 583 584 if( tr_sessionGetIncompleteDirEnabled( session ) ) 585 tor->incompleteDir = tr_strdup( tr_sessionGetIncompleteDir( session ) ); 581 586 582 587 tor->lastPieceSize = info->totalSize % info->pieceSize; … … 643 648 loaded = tr_torrentLoadResume( tor, ~0, ctor ); 644 649 650 refreshCurrentDir( tor ); 651 645 652 doStart = tor->isRunning; 646 653 tor->isRunning = 0; … … 775 782 tr_torrentSetDirty( tor ); 776 783 } 784 785 refreshCurrentDir( tor ); 777 786 } 778 787 … … 1242 1251 1243 1252 tr_free( tor->downloadDir ); 1253 tr_free( tor->incompleteDir ); 1244 1254 tr_free( tor->peer_id ); 1245 1255 … … 1597 1607 tor->needsSeedRatioCheck = TRUE; 1598 1608 tr_fdTorrentClose( tor->uniqueId ); 1609 1610 /* if the torrent is a seed now, 1611 * and the files used to be in the incompleteDir, 1612 * then move them to the destination directory */ 1613 if( tr_torrentIsSeed( tor ) && ( tor->currentDir == tor->incompleteDir ) ) 1614 tr_torrentSetLocation( tor, tor->downloadDir, TRUE, NULL, NULL ); 1615 1599 1616 fireCompletenessChange( tor, completeness ); 1600 1617 … … 1980 1997 1981 1998 time_t* 1982 tr_torrentGetMTimes( const tr_torrent * tor, 1983 size_t * setme_n ) 1999 tr_torrentGetMTimes( const tr_torrent * tor, size_t * setme_n ) 1984 2000 { 1985 2001 size_t i; … … 1992 2008 { 1993 2009 struct stat sb; 1994 char * path = tr_ buildPath( tor->downloadDir, tor->info.files[i].name, NULL);1995 if( !stat( path, &sb) )2010 char * path = tr_torrentFindFile( tor, i ); 2011 if( ( path != NULL ) && !stat( path, &sb ) && S_ISREG( sb.st_mode ) ) 1996 2012 { 1997 2013 #ifdef SYS_DARWIN … … 2125 2141 tr_torrentGetBytesLeftToAllocate( const tr_torrent * tor ) 2126 2142 { 2127 const tr_file * it; 2128 const tr_file * end; 2129 struct stat sb; 2143 tr_file_index_t i; 2130 2144 uint64_t bytesLeft = 0; 2131 2145 2132 2146 assert( tr_isTorrent( tor ) ); 2133 2147 2134 for( i t=tor->info.files, end=it+tor->info.fileCount; it!=end; ++it)2135 { 2136 if( ! it->dnd )2148 for( i=0; i<tor->info.fileCount; ++i ) 2149 { 2150 if( !tor->info.files[i].dnd ) 2137 2151 { 2138 char * path = tr_buildPath( tor->downloadDir, it->name, NULL ); 2139 2140 bytesLeft += it->length; 2141 2142 if( !stat( path, &sb ) 2143 && S_ISREG( sb.st_mode ) 2144 && ( (uint64_t)sb.st_size <= it->length ) ) 2152 struct stat sb; 2153 const uint64_t length = tor->info.files[i].length; 2154 char * path = tr_torrentFindFile( tor, i ); 2155 2156 bytesLeft += length; 2157 2158 if( ( path != NULL ) && !stat( path, &sb ) 2159 && S_ISREG( sb.st_mode ) 2160 && ( (uint64_t)sb.st_size <= length ) ) 2145 2161 bytesLeft -= sb.st_size; 2146 2162 … … 2229 2245 else if( S_ISREG( sb.st_mode ) && ( sb.st_size > 0 ) ) 2230 2246 { 2231 const char * sub = buf + strlen( tor-> downloadDir ) + strlen( TR_PATH_DELIMITER_STR );2247 const char * sub = buf + strlen( tor->currentDir ) + strlen( TR_PATH_DELIMITER_STR ); 2232 2248 const tr_bool isTorrentFile = tr_ptrArrayFindSorted( torrentFiles, sub, vstrcmp ) != NULL; 2233 2249 if( !isTorrentFile ) … … 2252 2268 const char * cpch = strchr( firstFile, TR_PATH_DELIMITER ); 2253 2269 char * tmp = cpch ? tr_strndup( firstFile, cpch - firstFile ) : NULL; 2254 char * root = tr_buildPath( tor->downloadDir, tmp, NULL ); 2255 2256 assert( tr_isTorrent( tor ) ); 2257 2258 for( f=0; f<tor->info.fileCount; ++f ) 2259 tr_ptrArrayInsertSorted( &torrentFiles, tor->info.files[f].name, vstrcmp ); 2270 char * root = tr_buildPath( tor->currentDir, tmp, NULL ); 2271 2272 assert( tr_isTorrent( tor ) ); 2273 2274 for( f=0; f<tor->info.fileCount; ++f ) { 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 ); 2277 } 2260 2278 2261 2279 /* build the set of folders and dirtyFolders */ … … 2270 2288 /* now blow away any remaining torrent files, such as torrent files in dirty folders */ 2271 2289 for( f=0; f<tor->info.fileCount; ++f ) { 2272 char * path = tr_buildPath( tor-> downloadDir, tor->info.files[f].name, NULL );2290 char * path = tr_buildPath( tor->currentDir, tor->info.files[f].name, NULL ); 2273 2291 fileFunc( path ); 2274 2292 tr_free( path ); … … 2293 2311 tr_ptrArrayDestruct( &dirtyFolders, tr_free ); 2294 2312 tr_ptrArrayDestruct( &folders, tr_free ); 2295 tr_ptrArrayDestruct( &torrentFiles, NULL);2313 tr_ptrArrayDestruct( &torrentFiles, tr_free ); 2296 2314 tr_free( root ); 2297 2315 tr_free( tmp ); … … 2313 2331 else { 2314 2332 /* torrent only has one file */ 2315 char * path = tr_ buildPath( tor->downloadDir, tor->info.files[0].name, NULL);2333 char * path = tr_torrentFindFile( tor, 0 ); 2316 2334 fileFunc( path ); 2317 2335 tr_free( path ); … … 2322 2340 **** 2323 2341 ***/ 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 } 2324 2351 2325 2352 struct LocationData … … 2345 2372 assert( tr_isTorrent( tor ) ); 2346 2373 2347 if( strcmp( location, tor-> downloadDir ) )2374 if( strcmp( location, tor->currentDir ) ) 2348 2375 { 2349 2376 tr_file_index_t i; … … 2367 2394 struct stat sb; 2368 2395 const tr_file * f = &tor->info.files[i]; 2369 char * oldpath = tr_ buildPath( tor->downloadDir, f->name, NULL);2370 char * newpath = tr_buildPath( location, f->name, NULL );2371 2372 if( do_move )2396 char * oldpath = tr_torrentFindFile( tor, i ); 2397 char * newpath = oldpath ? rebaseFile( tor, i, oldpath, location ) : NULL; 2398 2399 if( do_move && ( oldpath != NULL ) ) 2373 2400 { 2374 2401 errno = 0; … … 2484 2511 } 2485 2512 } 2513 2514 /*** 2515 **** 2516 ***/ 2517 2518 void 2519 tr_torrentFileCompleted( tr_torrent * tor, tr_file_index_t fileNum ) 2520 { 2521 char * oldpath = tr_torrentFindFile( tor, fileNum ); 2522 char * newpath = tr_strdup( oldpath ); 2523 char * pch = strrchr( newpath, '.' ); 2524 assert( !strcmp( pch, ".part" ) ); 2525 *pch = '\0'; 2526 2527 /* close the file so that we can reopen in read-only mode as needed */ 2528 tr_fdFileClose( tor, fileNum ); 2529 2530 /* strip the trailing ".part" from the filename */ 2531 if( rename( oldpath, newpath ) ) 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 } 2537 2538 /*** 2539 **** 2540 ***/ 2541 2542 enum 2543 { 2544 TR_FILE_PARTIAL = (1<<0), 2545 TR_FILE_INCOMPLETE_DIR = (1<<1) 2546 }; 2547 2548 static char* 2549 tr_torrentBuildFilename( const tr_torrent * tor, tr_file_index_t fileNo, int flags ) 2550 { 2551 const char * root; 2552 char * base; 2553 char * path; 2554 const tr_bool partial = ( flags & TR_FILE_PARTIAL ) != 0; 2555 const tr_bool incomplete = ( flags & TR_FILE_INCOMPLETE_DIR ) != 0; 2556 2557 assert( tr_isTorrent( tor ) ); 2558 assert( fileNo < tor->info.fileCount ); 2559 2560 if( incomplete && ( tor->incompleteDir != NULL ) ) 2561 root = tor->incompleteDir; 2562 else 2563 root = tor->downloadDir; 2564 2565 if( partial ) 2566 base = tr_strdup_printf( "%s.part", tor->info.files[fileNo].name ); 2567 else 2568 base = tr_strdup( tor->info.files[fileNo].name ); 2569 2570 path = tr_buildPath( root, base, NULL ); 2571 2572 /* cleanup */ 2573 tr_free( base ); 2574 return path; 2575 } 2576 2577 static tr_bool 2578 fileExists( const char * filename ) 2579 { 2580 struct stat sb; 2581 const tr_bool ok = !stat( filename, &sb ); 2582 return ok; 2583 } 2584 2585 char* 2586 tr_torrentFindFile( const tr_torrent * tor, tr_file_index_t fileNo ) 2587 { 2588 int i; 2589 char * filename; 2590 int flags[4]; 2591 int n = 0; 2592 2593 assert( tr_isTorrent( tor ) ); 2594 assert( fileNo < tor->info.fileCount ); 2595 2596 /* based on what we know about the torrent, 2597 * put the most likely hits first... */ 2598 if( tr_cpFileIsComplete( &tor->completion, fileNo ) ) { 2599 flags[n++] = 0; 2600 flags[n++] = TR_FILE_INCOMPLETE_DIR; 2601 flags[n++] = TR_FILE_PARTIAL; 2602 flags[n++] = TR_FILE_INCOMPLETE_DIR|TR_FILE_PARTIAL; 2603 } else { 2604 flags[n++] = TR_FILE_INCOMPLETE_DIR|TR_FILE_PARTIAL; 2605 flags[n++] = TR_FILE_PARTIAL; 2606 flags[n++] = TR_FILE_INCOMPLETE_DIR; 2607 flags[n++] = 0; 2608 } 2609 2610 for( i=0; i<n; ++i ) { 2611 filename = tr_torrentBuildFilename( tor, fileNo, flags[i] ); 2612 if( fileExists( filename )) 2613 break; 2614 tr_free( filename ); 2615 filename = NULL; 2616 } 2617 2618 return filename; 2619 } 2620 2621 /* Decide whether we should be looking for files in downloadDir or incompleteDir. */ 2622 static void 2623 refreshCurrentDir( tr_torrent * tor ) 2624 { 2625 const char * dir = tor->downloadDir; 2626 2627 if( tor->incompleteDir != NULL ) 2628 { 2629 char * tmp1 = tr_torrentBuildFilename( tor, 0, 0 ); 2630 char * tmp2 = tr_torrentBuildFilename( tor, 0, TR_FILE_PARTIAL ); 2631 2632 if( !fileExists( tmp1 ) && !fileExists( tmp2 ) ) 2633 dir = tor->incompleteDir; 2634 2635 tr_free( tmp2 ); 2636 tr_free( tmp1 ); 2637 } 2638 2639 assert( dir != NULL ); 2640 assert( ( dir == tor->downloadDir ) || ( dir == tor->incompleteDir ) ); 2641 tor->currentDir = dir; 2642 }
Note: See TracChangeset
for help on using the changeset viewer.