From 9b208d2777050be56aaa22195bc7e1b9dcf0dbdc Mon Sep 17 00:00:00 2001 From: Jordan Lee Date: Sun, 10 Jul 2011 17:34:03 +0000 Subject: [PATCH] (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" --- libtransmission/torrent.c | 91 ++++++++++++++++++++------------------- 1 file changed, 47 insertions(+), 44 deletions(-) diff --git a/libtransmission/torrent.c b/libtransmission/torrent.c index e6c566c34..36bbc0b2b 100644 --- a/libtransmission/torrent.c +++ b/libtransmission/torrent.c @@ -2634,6 +2634,36 @@ addDirtyFile( const char * root, tr_free( dir ); } +static bool +isSystemFile( const char * base ) +{ + int i; + static const char * stockFiles[] = { ".DS_Store", "desktop.ini", "Thumbs.db" }; + static const int stockFileCount = sizeof(stockFiles) / sizeof(stockFiles[0]); + + for( i=0; i */ + if( !memcmp( base, "._", 2 ) ) + return true; + + return false; +} + +static void +deleteLocalFile( const tr_torrent * tor, const char * filename, tr_fileFunc fileFunc ) +{ + struct stat sb; + + /* add safeguards for (1) making sure the file exists and + (2) that we haven't somehow walked up past the torrent's top directory... */ + if( !stat( filename, &sb ) ) + if( !tr_is_same_file( tor->currentDir, filename ) ) + fileFunc( filename ); +} + static void walkLocalData( const tr_torrent * tor, const char * root, @@ -2641,7 +2671,8 @@ walkLocalData( const tr_torrent * tor, const char * base, tr_ptrArray * torrentFiles, tr_ptrArray * folders, - tr_ptrArray * dirtyFolders ) + tr_ptrArray * dirtyFolders, + tr_fileFunc fileFunc ) { struct stat sb; char * buf = tr_buildPath( dir, base, NULL ); @@ -2657,29 +2688,25 @@ walkLocalData( const tr_torrent * tor, tr_ptrArrayInsertSorted( folders, tr_strdup( buf ), vstrcmp ); for( d = readdir( odir ); d != NULL; d = readdir( odir ) ) if( d->d_name && strcmp( d->d_name, "." ) && strcmp( d->d_name, ".." ) ) - walkLocalData( tor, root, buf, d->d_name, torrentFiles, folders, dirtyFolders ); + walkLocalData( tor, root, buf, d->d_name, torrentFiles, folders, dirtyFolders, fileFunc ); closedir( odir ); } else if( S_ISREG( sb.st_mode ) && ( sb.st_size > 0 ) ) { - const char * sub = buf + strlen( tor->currentDir ) + strlen( TR_PATH_DELIMITER_STR ); - const bool isTorrentFile = tr_ptrArrayFindSorted( torrentFiles, sub, vstrcmp ) != NULL; - if( !isTorrentFile ) - addDirtyFile( root, buf, dirtyFolders ); + if( isSystemFile( base ) ) + deleteLocalFile( tor, buf, fileFunc ); + else { + const char * sub = buf + strlen( tor->currentDir ) + strlen( TR_PATH_DELIMITER_STR ); + const bool isTorrentFile = tr_ptrArrayFindSorted( torrentFiles, sub, vstrcmp ) != NULL; + if( !isTorrentFile ) + addDirtyFile( root, buf, dirtyFolders ); + } } } tr_free( buf ); } -static void -deleteLocalFile( const char * filename, tr_fileFunc fileFunc ) -{ - struct stat sb; - if( !stat( filename, &sb ) ) /* if file exists... */ - fileFunc( filename ); -} - static void deleteLocalData( tr_torrent * tor, tr_fileFunc fileFunc ) { @@ -2701,18 +2728,18 @@ deleteLocalData( tr_torrent * tor, tr_fileFunc fileFunc ) } /* build the set of folders and dirtyFolders */ - walkLocalData( tor, root, root, NULL, &torrentFiles, &folders, &dirtyFolders ); + walkLocalData( tor, root, root, NULL, &torrentFiles, &folders, &dirtyFolders, fileFunc ); /* try to remove entire folders first, so that the recycle bin will be tidy */ s = (char**) tr_ptrArrayPeek( &folders, &n ); for( i=0; icurrentDir, tr_ptrArrayNth( &torrentFiles, i ), NULL ); - deleteLocalFile( path, fileFunc ); + deleteLocalFile( tor, path, fileFunc ); tr_free( path ); } @@ -2726,14 +2753,8 @@ deleteLocalData( tr_torrent * tor, tr_fileFunc fileFunc ) if( tr_ptrArrayFindSorted( &dirtyFolders, s[i], vstrcmp ) == NULL ) tr_ptrArrayInsertSorted( &cleanFolders, s[i], compareLongestFirst ); s = (char**) tr_ptrArrayPeek( &cleanFolders, &n ); - for( i=0; isession->cache, tor ); tr_fdTorrentClose( tor->session, tor->uniqueId ); - if( tor->info.fileCount > 1 ) - { - deleteLocalData( tor, fileFunc ); - } - else if( tor->info.fileCount == 1 ) - { - char * tmp; - - /* torrent only has one file */ - char * path = tr_buildPath( tor->currentDir, tor->info.files[0].name, NULL ); - deleteLocalFile( path, fileFunc ); - tr_free( path ); - - tmp = tr_torrentBuildPartial( tor, 0 ); - path = tr_buildPath( tor->currentDir, tmp, NULL ); - deleteLocalFile( path, fileFunc ); - tr_free( path ); - tr_free( tmp ); - } + deleteLocalData( tor, fileFunc ); } /***