Ignore:
Timestamp:
Jul 10, 2011, 5:34:03 PM (10 years ago)
Author:
jordan
Message:

(trunk libT) possible fix for three related tickets. still needs more testing.
#3732 "Delete system files when removing torrent data"
#4224 "Folders don't get deleted"
#3871 "torrent-set-location does not delete old folder if only one file in torrent"

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/torrent.c

    r12531 r12540  
    26352635}
    26362636
     2637static bool
     2638isSystemFile( const char * base )
     2639{
     2640    int i;
     2641    static const char * stockFiles[] = { ".DS_Store", "desktop.ini", "Thumbs.db" };
     2642    static const int stockFileCount = sizeof(stockFiles) / sizeof(stockFiles[0]);
     2643
     2644    for( i=0; i<stockFileCount; ++i )
     2645        if( !strcmp( base, stockFiles[i] ) )
     2646            return true;
     2647
     2648    /* check for resource forks. <http://support.apple.com/kb/TA20578> */
     2649    if( !memcmp( base, "._", 2 ) )
     2650        return true;
     2651
     2652    return false;
     2653}
     2654
     2655static void
     2656deleteLocalFile( const tr_torrent * tor, const char * filename, tr_fileFunc fileFunc )
     2657{
     2658    struct stat sb;
     2659
     2660    /* add safeguards for (1) making sure the file exists and
     2661       (2) that we haven't somehow walked up past the torrent's top directory... */
     2662    if( !stat( filename, &sb ) )
     2663        if( !tr_is_same_file( tor->currentDir, filename ) )
     2664            fileFunc( filename );
     2665}
     2666
    26372667static void
    26382668walkLocalData( const tr_torrent * tor,
     
    26422672               tr_ptrArray      * torrentFiles,
    26432673               tr_ptrArray      * folders,
    2644                tr_ptrArray      * dirtyFolders )
     2674               tr_ptrArray      * dirtyFolders,
     2675               tr_fileFunc        fileFunc )
    26452676{
    26462677    struct stat sb;
     
    26582689            for( d = readdir( odir ); d != NULL; d = readdir( odir ) )
    26592690                if( d->d_name && strcmp( d->d_name, "." ) && strcmp( d->d_name, ".." ) )
    2660                     walkLocalData( tor, root, buf, d->d_name, torrentFiles, folders, dirtyFolders );
     2691                    walkLocalData( tor, root, buf, d->d_name, torrentFiles, folders, dirtyFolders, fileFunc );
    26612692            closedir( odir );
    26622693        }
    26632694        else if( S_ISREG( sb.st_mode ) && ( sb.st_size > 0 ) )
    26642695        {
    2665             const char * sub = buf + strlen( tor->currentDir ) + strlen( TR_PATH_DELIMITER_STR );
    2666             const bool isTorrentFile = tr_ptrArrayFindSorted( torrentFiles, sub, vstrcmp ) != NULL;
    2667             if( !isTorrentFile )
    2668                 addDirtyFile( root, buf, dirtyFolders );
     2696            if( isSystemFile( base ) )
     2697                deleteLocalFile( tor, buf, fileFunc );
     2698            else {
     2699                 const char * sub = buf + strlen( tor->currentDir ) + strlen( TR_PATH_DELIMITER_STR );
     2700                const bool isTorrentFile = tr_ptrArrayFindSorted( torrentFiles, sub, vstrcmp ) != NULL;
     2701                if( !isTorrentFile )
     2702                    addDirtyFile( root, buf, dirtyFolders );
     2703            }
    26692704        }
    26702705    }
    26712706
    26722707    tr_free( buf );
    2673 }
    2674 
    2675 static void
    2676 deleteLocalFile( const char * filename, tr_fileFunc fileFunc )
    2677 {
    2678     struct stat sb;
    2679     if( !stat( filename, &sb ) ) /* if file exists... */
    2680         fileFunc( filename );
    26812708}
    26822709
     
    27022729
    27032730    /* build the set of folders and dirtyFolders */
    2704     walkLocalData( tor, root, root, NULL, &torrentFiles, &folders, &dirtyFolders );
     2731    walkLocalData( tor, root, root, NULL, &torrentFiles, &folders, &dirtyFolders, fileFunc );
    27052732
    27062733    /* try to remove entire folders first, so that the recycle bin will be tidy */
     
    27082735    for( i=0; i<n; ++i )
    27092736        if( tr_ptrArrayFindSorted( &dirtyFolders, s[i], vstrcmp ) == NULL )
    2710             deleteLocalFile( s[i], fileFunc );
     2737            deleteLocalFile( tor, s[i], fileFunc );
    27112738
    27122739    /* now blow away any remaining torrent files, such as torrent files in dirty folders */
    27132740    for( i=0, n=tr_ptrArraySize( &torrentFiles ); i<n; ++i ) {
    27142741        char * path = tr_buildPath( tor->currentDir, tr_ptrArrayNth( &torrentFiles, i ), NULL );
    2715         deleteLocalFile( path, fileFunc );
     2742        deleteLocalFile( tor, path, fileFunc );
    27162743        tr_free( path );
    27172744    }
     
    27272754                tr_ptrArrayInsertSorted( &cleanFolders, s[i], compareLongestFirst );
    27282755        s = (char**) tr_ptrArrayPeek( &cleanFolders, &n );
    2729         for( i=0; i<n; ++i ) {
    2730 #ifdef SYS_DARWIN
    2731             char * dsStore = tr_buildPath( s[i], ".DS_Store", NULL );
    2732             deleteLocalFile( dsStore, fileFunc );
    2733             tr_free( dsStore );
    2734 #endif
    2735             deleteLocalFile( s[i], fileFunc );
    2736         }
     2756        for( i=0; i<n; ++i )
     2757            deleteLocalFile( tor, s[i], fileFunc );
    27372758        tr_ptrArrayDestruct( &cleanFolders, NULL );
    27382759    }
     
    27582779    tr_fdTorrentClose( tor->session, tor->uniqueId );
    27592780
    2760     if( tor->info.fileCount > 1 )
    2761     {
    2762         deleteLocalData( tor, fileFunc );
    2763     }
    2764     else if( tor->info.fileCount == 1 )
    2765     {
    2766         char * tmp;
    2767 
    2768         /* torrent only has one file */
    2769         char * path = tr_buildPath( tor->currentDir, tor->info.files[0].name, NULL );
    2770         deleteLocalFile( path, fileFunc );
    2771         tr_free( path );
    2772 
    2773         tmp = tr_torrentBuildPartial( tor, 0 );
    2774         path = tr_buildPath( tor->currentDir, tmp, NULL );
    2775         deleteLocalFile( path, fileFunc );
    2776         tr_free( path );
    2777         tr_free( tmp );
    2778     }
     2781    deleteLocalData( tor, fileFunc );
    27792782}
    27802783
Note: See TracChangeset for help on using the changeset viewer.